xref: /freebsd/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c (revision 0ce9a414adc33af29607adbd81e0760e014fcd76)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or https://opensource.org/licenses/CDDL-1.0.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
23  * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
24  * LLNL-CODE-403049.
25  * Rewritten for Linux by:
26  *   Rohan Puri <rohan.puri15@gmail.com>
27  *   Brian Behlendorf <behlendorf1@llnl.gov>
28  */
29 
30 #include <sys/zfs_znode.h>
31 #include <sys/zfs_vfsops.h>
32 #include <sys/zfs_vnops.h>
33 #include <sys/zfs_ctldir.h>
34 #include <sys/zpl.h>
35 #include <sys/dmu.h>
36 #include <sys/dsl_dataset.h>
37 #include <sys/zap.h>
38 
39 /*
40  * Common open routine.  Disallow any write access.
41  */
42 static int
43 zpl_common_open(struct inode *ip, struct file *filp)
44 {
45 	if (blk_mode_is_open_write(filp->f_mode))
46 		return (-EACCES);
47 
48 	return (generic_file_open(ip, filp));
49 }
50 
51 /*
52  * Get root directory contents.
53  */
54 static int
55 zpl_root_iterate(struct file *filp, struct dir_context *ctx)
56 {
57 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
58 	int error = 0;
59 
60 	if (zfsvfs->z_show_ctldir == ZFS_SNAPDIR_DISABLED) {
61 		return (SET_ERROR(ENOENT));
62 	}
63 
64 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
65 		return (error);
66 
67 	if (!dir_emit_dots(filp, ctx))
68 		goto out;
69 
70 	if (ctx->pos == 2) {
71 		if (!dir_emit(ctx, ZFS_SNAPDIR_NAME,
72 		    strlen(ZFS_SNAPDIR_NAME), ZFSCTL_INO_SNAPDIR, DT_DIR))
73 			goto out;
74 
75 		ctx->pos++;
76 	}
77 
78 	if (ctx->pos == 3) {
79 		if (!dir_emit(ctx, ZFS_SHAREDIR_NAME,
80 		    strlen(ZFS_SHAREDIR_NAME), ZFSCTL_INO_SHARES, DT_DIR))
81 			goto out;
82 
83 		ctx->pos++;
84 	}
85 out:
86 	zpl_exit(zfsvfs, FTAG);
87 
88 	return (error);
89 }
90 
91 /*
92  * Get root directory attributes.
93  */
94 static int
95 #ifdef HAVE_IDMAP_IOPS_GETATTR
96 zpl_root_getattr_impl(struct mnt_idmap *user_ns,
97     const struct path *path, struct kstat *stat, u32 request_mask,
98     unsigned int query_flags)
99 #elif defined(HAVE_USERNS_IOPS_GETATTR)
100 zpl_root_getattr_impl(struct user_namespace *user_ns,
101     const struct path *path, struct kstat *stat, u32 request_mask,
102     unsigned int query_flags)
103 #else
104 zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
105     u32 request_mask, unsigned int query_flags)
106 #endif
107 {
108 	(void) request_mask, (void) query_flags;
109 	struct inode *ip = path->dentry->d_inode;
110 
111 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
112 #ifdef HAVE_GENERIC_FILLATTR_USERNS
113 	generic_fillattr(user_ns, ip, stat);
114 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
115 	generic_fillattr(user_ns, ip, stat);
116 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
117 	generic_fillattr(user_ns, request_mask, ip, stat);
118 #else
119 	(void) user_ns;
120 #endif
121 #else
122 	generic_fillattr(ip, stat);
123 #endif
124 	stat->atime = current_time(ip);
125 
126 	return (0);
127 }
128 ZPL_GETATTR_WRAPPER(zpl_root_getattr);
129 
130 static struct dentry *
131 zpl_root_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
132 {
133 	cred_t *cr = CRED();
134 	struct inode *ip;
135 	int error;
136 
137 	crhold(cr);
138 	error = -zfsctl_root_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL);
139 	ASSERT3S(error, <=, 0);
140 	crfree(cr);
141 
142 	if (error) {
143 		if (error == -ENOENT)
144 			return (d_splice_alias(NULL, dentry));
145 		else
146 			return (ERR_PTR(error));
147 	}
148 
149 	return (d_splice_alias(ip, dentry));
150 }
151 
152 /*
153  * The '.zfs' control directory file and inode operations.
154  */
155 const struct file_operations zpl_fops_root = {
156 	.open		= zpl_common_open,
157 	.llseek		= generic_file_llseek,
158 	.read		= generic_read_dir,
159 	.iterate_shared	= zpl_root_iterate,
160 };
161 
162 const struct inode_operations zpl_ops_root = {
163 	.lookup		= zpl_root_lookup,
164 	.getattr	= zpl_root_getattr,
165 };
166 
167 static struct vfsmount *
168 zpl_snapdir_automount(struct path *path)
169 {
170 	int error;
171 
172 	error = -zfsctl_snapshot_mount(path, 0);
173 	if (error)
174 		return (ERR_PTR(error));
175 
176 	/*
177 	 * Rather than returning the new vfsmount for the snapshot we must
178 	 * return NULL to indicate a mount collision.  This is done because
179 	 * the user space mount calls do_add_mount() which adds the vfsmount
180 	 * to the name space.  If we returned the new mount here it would be
181 	 * added again to the vfsmount list resulting in list corruption.
182 	 */
183 	return (NULL);
184 }
185 
186 /*
187  * Negative dentries must always be revalidated so newly created snapshots
188  * can be detected and automounted.  Normal dentries should be kept because
189  * as of the 3.18 kernel revaliding the mountpoint dentry will result in
190  * the snapshot being immediately unmounted.
191  */
192 #ifdef HAVE_D_REVALIDATE_4ARGS
193 static int
194 zpl_snapdir_revalidate(struct inode *dir, const struct qstr *name,
195     struct dentry *dentry, unsigned int flags)
196 #else
197 static int
198 zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
199 #endif
200 {
201 	return (!!dentry->d_inode);
202 }
203 
204 static dentry_operations_t zpl_dops_snapdirs = {
205 /*
206  * Auto mounting of snapshots is only supported for 2.6.37 and
207  * newer kernels.  Prior to this kernel the ops->follow_link()
208  * callback was used as a hack to trigger the mount.  The
209  * resulting vfsmount was then explicitly grafted in to the
210  * name space.  While it might be possible to add compatibility
211  * code to accomplish this it would require considerable care.
212  */
213 	.d_automount	= zpl_snapdir_automount,
214 	.d_revalidate	= zpl_snapdir_revalidate,
215 };
216 
217 static struct dentry *
218 zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
219     unsigned int flags)
220 {
221 	fstrans_cookie_t cookie;
222 	cred_t *cr = CRED();
223 	struct inode *ip = NULL;
224 	int error;
225 
226 	crhold(cr);
227 	cookie = spl_fstrans_mark();
228 	error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
229 	    0, cr, NULL, NULL);
230 	ASSERT3S(error, <=, 0);
231 	spl_fstrans_unmark(cookie);
232 	crfree(cr);
233 
234 	if (error && error != -ENOENT)
235 		return (ERR_PTR(error));
236 
237 	ASSERT(error == 0 || ip == NULL);
238 	d_clear_d_op(dentry);
239 	d_set_d_op(dentry, &zpl_dops_snapdirs);
240 	dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
241 
242 	return (d_splice_alias(ip, dentry));
243 }
244 
245 static int
246 zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
247 {
248 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
249 	fstrans_cookie_t cookie;
250 	char snapname[MAXNAMELEN];
251 	boolean_t case_conflict;
252 	uint64_t id, pos;
253 	int error = 0;
254 
255 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
256 		return (error);
257 	cookie = spl_fstrans_mark();
258 
259 	if (!dir_emit_dots(filp, ctx))
260 		goto out;
261 
262 	/* Start the position at 0 if it already emitted . and .. */
263 	pos = (ctx->pos == 2 ? 0 : ctx->pos);
264 	while (error == 0) {
265 		dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
266 		error = -dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN,
267 		    snapname, &id, &pos, &case_conflict);
268 		dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
269 		if (error)
270 			goto out;
271 
272 		if (!dir_emit(ctx, snapname, strlen(snapname),
273 		    ZFSCTL_INO_SHARES - id, DT_DIR))
274 			goto out;
275 
276 		ctx->pos = pos;
277 	}
278 out:
279 	spl_fstrans_unmark(cookie);
280 	zpl_exit(zfsvfs, FTAG);
281 
282 	if (error == -ENOENT)
283 		return (0);
284 
285 	return (error);
286 }
287 
288 static int
289 #ifdef HAVE_IOPS_RENAME_USERNS
290 zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
291     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
292     unsigned int flags)
293 #elif defined(HAVE_IOPS_RENAME_IDMAP)
294 zpl_snapdir_rename2(struct mnt_idmap *user_ns, struct inode *sdip,
295     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
296     unsigned int flags)
297 #else
298 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
299     struct inode *tdip, struct dentry *tdentry, unsigned int flags)
300 #endif
301 {
302 	cred_t *cr = CRED();
303 	int error;
304 
305 	/* We probably don't want to support renameat2(2) in ctldir */
306 	if (flags)
307 		return (-EINVAL);
308 
309 	crhold(cr);
310 	error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
311 	    tdip, dname(tdentry), cr, 0);
312 	ASSERT3S(error, <=, 0);
313 	crfree(cr);
314 
315 	return (error);
316 }
317 
318 #if (!defined(HAVE_RENAME_WANTS_FLAGS) && \
319 	!defined(HAVE_IOPS_RENAME_USERNS) && \
320 	!defined(HAVE_IOPS_RENAME_IDMAP))
321 static int
322 zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
323     struct inode *tdip, struct dentry *tdentry)
324 {
325 	return (zpl_snapdir_rename2(sdip, sdentry, tdip, tdentry, 0));
326 }
327 #endif
328 
329 static int
330 zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
331 {
332 	cred_t *cr = CRED();
333 	int error;
334 
335 	crhold(cr);
336 	error = -zfsctl_snapdir_remove(dip, dname(dentry), cr, 0);
337 	ASSERT3S(error, <=, 0);
338 	crfree(cr);
339 
340 	return (error);
341 }
342 
343 static int
344 #ifdef HAVE_IOPS_MKDIR_USERNS
345 zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
346     struct dentry *dentry, umode_t mode)
347 #elif defined(HAVE_IOPS_MKDIR_IDMAP)
348 zpl_snapdir_mkdir(struct mnt_idmap *user_ns, struct inode *dip,
349     struct dentry *dentry, umode_t mode)
350 #else
351 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
352 #endif
353 {
354 	cred_t *cr = CRED();
355 	vattr_t *vap;
356 	struct inode *ip;
357 	int error;
358 
359 	crhold(cr);
360 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
361 #if (defined(HAVE_IOPS_MKDIR_USERNS) || defined(HAVE_IOPS_MKDIR_IDMAP))
362 	zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns);
363 #else
364 	zpl_vap_init(vap, dip, mode | S_IFDIR, cr, zfs_init_idmap);
365 #endif
366 
367 	error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
368 	if (error == 0) {
369 		d_clear_d_op(dentry);
370 		d_set_d_op(dentry, &zpl_dops_snapdirs);
371 		d_instantiate(dentry, ip);
372 	}
373 
374 	kmem_free(vap, sizeof (vattr_t));
375 	ASSERT3S(error, <=, 0);
376 	crfree(cr);
377 
378 	return (error);
379 }
380 
381 /*
382  * Get snapshot directory attributes.
383  */
384 static int
385 #ifdef HAVE_IDMAP_IOPS_GETATTR
386 zpl_snapdir_getattr_impl(struct mnt_idmap *user_ns,
387     const struct path *path, struct kstat *stat, u32 request_mask,
388     unsigned int query_flags)
389 #elif defined(HAVE_USERNS_IOPS_GETATTR)
390 zpl_snapdir_getattr_impl(struct user_namespace *user_ns,
391     const struct path *path, struct kstat *stat, u32 request_mask,
392     unsigned int query_flags)
393 #else
394 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
395     u32 request_mask, unsigned int query_flags)
396 #endif
397 {
398 	(void) request_mask, (void) query_flags;
399 	struct inode *ip = path->dentry->d_inode;
400 	zfsvfs_t *zfsvfs = ITOZSB(ip);
401 	int error;
402 
403 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
404 		return (error);
405 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
406 #ifdef HAVE_GENERIC_FILLATTR_USERNS
407 	generic_fillattr(user_ns, ip, stat);
408 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
409 	generic_fillattr(user_ns, ip, stat);
410 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
411 	generic_fillattr(user_ns, request_mask, ip, stat);
412 #else
413 	(void) user_ns;
414 #endif
415 #else
416 	generic_fillattr(ip, stat);
417 #endif
418 
419 	stat->nlink = stat->size = 2;
420 
421 	dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os);
422 	if (dsl_dataset_phys(ds)->ds_snapnames_zapobj != 0) {
423 		uint64_t snap_count;
424 		int err = zap_count(
425 		    dmu_objset_pool(ds->ds_objset)->dp_meta_objset,
426 		    dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count);
427 		if (err != 0) {
428 			zpl_exit(zfsvfs, FTAG);
429 			return (-err);
430 		}
431 		stat->nlink += snap_count;
432 	}
433 
434 	stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
435 	stat->atime = current_time(ip);
436 	zpl_exit(zfsvfs, FTAG);
437 
438 	return (0);
439 }
440 ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
441 
442 /*
443  * The '.zfs/snapshot' directory file operations.  These mainly control
444  * generating the list of available snapshots when doing an 'ls' in the
445  * directory.  See zpl_snapdir_readdir().
446  */
447 const struct file_operations zpl_fops_snapdir = {
448 	.open		= zpl_common_open,
449 	.llseek		= generic_file_llseek,
450 	.read		= generic_read_dir,
451 	.iterate_shared	= zpl_snapdir_iterate,
452 
453 };
454 
455 /*
456  * The '.zfs/snapshot' directory inode operations.  These mainly control
457  * creating an inode for a snapshot directory and initializing the needed
458  * infrastructure to automount the snapshot.  See zpl_snapdir_lookup().
459  */
460 const struct inode_operations zpl_ops_snapdir = {
461 	.lookup		= zpl_snapdir_lookup,
462 	.getattr	= zpl_snapdir_getattr,
463 #if (defined(HAVE_RENAME_WANTS_FLAGS) || \
464 	defined(HAVE_IOPS_RENAME_USERNS) || \
465 	defined(HAVE_IOPS_RENAME_IDMAP))
466 	.rename		= zpl_snapdir_rename2,
467 #else
468 	.rename		= zpl_snapdir_rename,
469 #endif
470 	.rmdir		= zpl_snapdir_rmdir,
471 	.mkdir		= zpl_snapdir_mkdir,
472 };
473 
474 static struct dentry *
475 zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
476     unsigned int flags)
477 {
478 	fstrans_cookie_t cookie;
479 	cred_t *cr = CRED();
480 	struct inode *ip = NULL;
481 	int error;
482 
483 	crhold(cr);
484 	cookie = spl_fstrans_mark();
485 	error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
486 	    0, cr, NULL, NULL);
487 	ASSERT3S(error, <=, 0);
488 	spl_fstrans_unmark(cookie);
489 	crfree(cr);
490 
491 	if (error) {
492 		if (error == -ENOENT)
493 			return (d_splice_alias(NULL, dentry));
494 		else
495 			return (ERR_PTR(error));
496 	}
497 
498 	return (d_splice_alias(ip, dentry));
499 }
500 
501 static int
502 zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
503 {
504 	fstrans_cookie_t cookie;
505 	cred_t *cr = CRED();
506 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
507 	znode_t *dzp;
508 	int error = 0;
509 
510 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
511 		return (error);
512 	cookie = spl_fstrans_mark();
513 
514 	if (zfsvfs->z_shares_dir == 0) {
515 		dir_emit_dots(filp, ctx);
516 		goto out;
517 	}
518 
519 	error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
520 	if (error)
521 		goto out;
522 
523 	crhold(cr);
524 	error = -zfs_readdir(ZTOI(dzp), ctx, cr);
525 	crfree(cr);
526 
527 	iput(ZTOI(dzp));
528 out:
529 	spl_fstrans_unmark(cookie);
530 	zpl_exit(zfsvfs, FTAG);
531 	ASSERT3S(error, <=, 0);
532 
533 	return (error);
534 }
535 
536 static int
537 #ifdef HAVE_USERNS_IOPS_GETATTR
538 zpl_shares_getattr_impl(struct user_namespace *user_ns,
539     const struct path *path, struct kstat *stat, u32 request_mask,
540     unsigned int query_flags)
541 #elif defined(HAVE_IDMAP_IOPS_GETATTR)
542 zpl_shares_getattr_impl(struct mnt_idmap *user_ns,
543     const struct path *path, struct kstat *stat, u32 request_mask,
544     unsigned int query_flags)
545 #else
546 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
547     u32 request_mask, unsigned int query_flags)
548 #endif
549 {
550 	(void) request_mask, (void) query_flags;
551 	struct inode *ip = path->dentry->d_inode;
552 	zfsvfs_t *zfsvfs = ITOZSB(ip);
553 	znode_t *dzp;
554 	int error;
555 
556 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
557 		return (error);
558 
559 	if (zfsvfs->z_shares_dir == 0) {
560 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
561 #ifdef HAVE_GENERIC_FILLATTR_USERNS
562 		generic_fillattr(user_ns, path->dentry->d_inode, stat);
563 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
564 		generic_fillattr(user_ns, path->dentry->d_inode, stat);
565 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
566 	generic_fillattr(user_ns, request_mask, ip, stat);
567 #else
568 		(void) user_ns;
569 #endif
570 #else
571 		generic_fillattr(path->dentry->d_inode, stat);
572 #endif
573 		stat->nlink = stat->size = 2;
574 		stat->atime = current_time(ip);
575 		zpl_exit(zfsvfs, FTAG);
576 		return (0);
577 	}
578 
579 	error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
580 	if (error == 0) {
581 #ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK
582 		error = -zfs_getattr_fast(user_ns, request_mask, ZTOI(dzp),
583 		    stat);
584 #elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
585 		error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
586 #else
587 		error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
588 #endif
589 		iput(ZTOI(dzp));
590 	}
591 
592 	zpl_exit(zfsvfs, FTAG);
593 	ASSERT3S(error, <=, 0);
594 
595 	return (error);
596 }
597 ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
598 
599 /*
600  * The '.zfs/shares' directory file operations.
601  */
602 const struct file_operations zpl_fops_shares = {
603 	.open		= zpl_common_open,
604 	.llseek		= generic_file_llseek,
605 	.read		= generic_read_dir,
606 	.iterate_shared	= zpl_shares_iterate,
607 };
608 
609 /*
610  * The '.zfs/shares' directory inode operations.
611  */
612 const struct inode_operations zpl_ops_shares = {
613 	.lookup		= zpl_shares_lookup,
614 	.getattr	= zpl_shares_getattr,
615 };
616