xref: /linux/fs/nullfs.c (revision 2a31b5378c6db9c4a8d399e5d10d32cd4b732bef)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2026 Christian Brauner <brauner@kernel.org> */
3 #include <linux/fs/super_types.h>
4 #include <linux/fs_context.h>
5 #include <linux/magic.h>
6 #include <linux/splice.h>
7 #include <linux/uio.h>
8 
9 #include "mount.h"
10 
11 static const struct super_operations nullfs_super_operations = {
12 	.statfs	= simple_statfs,
13 };
14 
15 static loff_t nullfs_dir_llseek(struct file *file, loff_t offset, int whence)
16 {
17 	/* an empty directory has two entries . and .. at offsets 0 and 1 */
18 	return generic_file_llseek_size(file, offset, whence, 2, 2);
19 }
20 
21 static int nullfs_dir_readdir(struct file *file, struct dir_context *ctx)
22 {
23 	dir_emit_dots(file, ctx);
24 	return 0;
25 }
26 
27 /* the one inode of nullfs is shared by every holder, so no locks on it */
28 static int nullfs_nolock(struct file *file, int cmd, struct file_lock *fl)
29 {
30 	return -ENOLCK;
31 }
32 
33 /* what libfs gives an empty directory, plus the refusal of file locks */
34 static const struct file_operations nullfs_dir_operations = {
35 	.llseek		= nullfs_dir_llseek,
36 	.read		= generic_read_dir,
37 	.iterate_shared	= nullfs_dir_readdir,
38 	.fsync		= noop_fsync,
39 	.lock		= nullfs_nolock,
40 	.flock		= nullfs_nolock,
41 	.fop_flags	= FOP_IMMUTABLE,
42 };
43 
44 static ssize_t nullfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
45 {
46 	return 0;
47 }
48 
49 static ssize_t nullfs_file_splice_read(struct file *in, loff_t *ppos,
50 				       struct pipe_inode_info *pipe,
51 				       size_t len, unsigned int flags)
52 {
53 	return 0;
54 }
55 
56 static ssize_t nullfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
57 {
58 	size_t count = iov_iter_count(from);
59 
60 	iov_iter_advance(from, count);
61 	return count;
62 }
63 
64 static int nullfs_pipe_to_null(struct pipe_inode_info *pipe,
65 			       struct pipe_buffer *buf, struct splice_desc *sd)
66 {
67 	return sd->len;
68 }
69 
70 static ssize_t nullfs_file_splice_write(struct pipe_inode_info *pipe,
71 					struct file *out, loff_t *ppos,
72 					size_t len, unsigned int flags)
73 {
74 	return splice_from_pipe(pipe, out, ppos, len, flags, nullfs_pipe_to_null);
75 }
76 
77 static int nullfs_file_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
78 			       struct iattr *attr)
79 {
80 	if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
81 		return -EPERM;
82 	return 0;
83 }
84 
85 static const struct inode_operations nullfs_file_inode_operations = {
86 	.setattr	= nullfs_file_setattr,
87 };
88 
89 static const struct file_operations nullfs_file_operations = {
90 	.llseek		= generic_file_llseek,
91 	.read_iter	= nullfs_file_read_iter,
92 	.write_iter	= nullfs_file_write_iter,
93 	.splice_read	= nullfs_file_splice_read,
94 	.splice_write	= nullfs_file_splice_write,
95 	.fsync		= noop_fsync,
96 	.lock		= nullfs_nolock,
97 	.flock		= nullfs_nolock,
98 };
99 
100 /*
101  * An empty regular file on @sb as a dentry of its own, never hashed under
102  * the root so no lookup finds it.
103  */
104 struct dentry *nullfs_new_file(struct super_block *sb)
105 {
106 	struct dentry *dentry;
107 	struct inode *inode;
108 
109 	inode = new_inode(sb);
110 	if (!inode)
111 		return ERR_PTR(-ENOMEM);
112 
113 	/* the root directory is 1 */
114 	inode->i_ino = 2;
115 	inode->i_mode = S_IFREG | 0666;
116 	inode->i_op = &nullfs_file_inode_operations;
117 	inode->i_fop = &nullfs_file_operations;
118 	simple_inode_init_ts(inode);
119 	inode->i_flags |= S_NOATIME;
120 
121 	dentry = d_alloc_anon(sb);
122 	if (!dentry) {
123 		iput(inode);
124 		return ERR_PTR(-ENOMEM);
125 	}
126 	d_instantiate(dentry, inode);
127 	return dentry;
128 }
129 
130 static int nullfs_fs_fill_super(struct super_block *s, struct fs_context *fc)
131 {
132 	struct inode *inode;
133 
134 	s->s_maxbytes		= MAX_LFS_FILESIZE;
135 	s->s_blocksize		= PAGE_SIZE;
136 	s->s_blocksize_bits	= PAGE_SHIFT;
137 	s->s_magic		= NULL_FS_MAGIC;
138 	s->s_op			= &nullfs_super_operations;
139 	s->s_export_op		= NULL;
140 	s->s_xattr		= NULL;
141 	s->s_time_gran		= 1;
142 	s->s_d_flags		= 0;
143 
144 	inode = new_inode(s);
145 	if (!inode)
146 		return -ENOMEM;
147 
148 	/* nullfs is permanently empty... */
149 	make_empty_dir_inode(inode);
150 	inode->i_fop = &nullfs_dir_operations;
151 	simple_inode_init_ts(inode);
152 	inode->i_ino	= 1;
153 	/* ... and immutable, reading it leaves no trace either. */
154 	inode->i_flags |= S_IMMUTABLE | S_NOATIME;
155 
156 	s->s_root = d_make_root(inode);
157 	if (!s->s_root)
158 		return -ENOMEM;
159 
160 	return 0;
161 }
162 
163 static int nullfs_fs_get_tree(struct fs_context *fc)
164 {
165 	return get_tree_nodev(fc, nullfs_fs_fill_super);
166 }
167 
168 static const struct fs_context_operations nullfs_fs_context_ops = {
169 	.get_tree	= nullfs_fs_get_tree,
170 };
171 
172 static int nullfs_init_fs_context(struct fs_context *fc)
173 {
174 	fc->ops		= &nullfs_fs_context_ops;
175 	fc->sb_flags	|= SB_NOUSER;
176 	fc->s_iflags	|= SB_I_NOEXEC | SB_I_NODEV;
177 	return 0;
178 }
179 
180 struct file_system_type nullfs_fs_type = {
181 	.name			= "nullfs",
182 	.fs_flags		= FS_DISALLOW_NOTIFY,
183 	.init_fs_context	= nullfs_init_fs_context,
184 	.kill_sb		= kill_anon_super,
185 };
186