]> git.proxmox.com Git - mirror_zfs.git/blob - module/zfs/zpl_super.c
Mark additional functions as PF_FSTRANS
[mirror_zfs.git] / module / zfs / zpl_super.c
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 http://www.opensolaris.org/os/licensing.
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 */
24
25
26 #include <sys/zfs_vfsops.h>
27 #include <sys/zfs_vnops.h>
28 #include <sys/zfs_znode.h>
29 #include <sys/zfs_ctldir.h>
30 #include <sys/zpl.h>
31
32
33 static struct inode *
34 zpl_inode_alloc(struct super_block *sb)
35 {
36 struct inode *ip;
37
38 VERIFY3S(zfs_inode_alloc(sb, &ip), ==, 0);
39 ip->i_version = 1;
40
41 return (ip);
42 }
43
44 static void
45 zpl_inode_destroy(struct inode *ip)
46 {
47 ASSERT(atomic_read(&ip->i_count) == 0);
48 zfs_inode_destroy(ip);
49 }
50
51 /*
52 * Called from __mark_inode_dirty() to reflect that something in the
53 * inode has changed. We use it to ensure the znode system attributes
54 * are always strictly update to date with respect to the inode.
55 */
56 #ifdef HAVE_DIRTY_INODE_WITH_FLAGS
57 static void
58 zpl_dirty_inode(struct inode *ip, int flags)
59 {
60 zfs_dirty_inode(ip, flags);
61 }
62 #else
63 static void
64 zpl_dirty_inode(struct inode *ip)
65 {
66 zfs_dirty_inode(ip, 0);
67 }
68 #endif /* HAVE_DIRTY_INODE_WITH_FLAGS */
69
70 /*
71 * When ->drop_inode() is called its return value indicates if the
72 * inode should be evicted from the inode cache. If the inode is
73 * unhashed and has no links the default policy is to evict it
74 * immediately.
75 *
76 * Prior to 2.6.36 this eviction was accomplished by the vfs calling
77 * ->delete_inode(). It was ->delete_inode()'s responsibility to
78 * truncate the inode pages and call clear_inode(). The call to
79 * clear_inode() synchronously invalidates all the buffers and
80 * calls ->clear_inode(). It was ->clear_inode()'s responsibility
81 * to cleanup and filesystem specific data before freeing the inode.
82 *
83 * This elaborate mechanism was replaced by ->evict_inode() which
84 * does the job of both ->delete_inode() and ->clear_inode(). It
85 * will be called exactly once, and when it returns the inode must
86 * be in a state where it can simply be freed.i
87 *
88 * The ->evict_inode() callback must minimally truncate the inode pages,
89 * and call clear_inode(). For 2.6.35 and later kernels this will
90 * simply update the inode state, with the sync occurring before the
91 * truncate in evict(). For earlier kernels clear_inode() maps to
92 * end_writeback() which is responsible for completing all outstanding
93 * write back. In either case, once this is done it is safe to cleanup
94 * any remaining inode specific data via zfs_inactive().
95 * remaining filesystem specific data.
96 */
97 #ifdef HAVE_EVICT_INODE
98 static void
99 zpl_evict_inode(struct inode *ip)
100 {
101 fstrans_cookie_t cookie;
102
103 cookie = spl_fstrans_mark();
104 truncate_setsize(ip, 0);
105 clear_inode(ip);
106 zfs_inactive(ip);
107 spl_fstrans_unmark(cookie);
108 }
109
110 #else
111
112 static void
113 zpl_drop_inode(struct inode *ip)
114 {
115 generic_delete_inode(ip);
116 }
117
118 static void
119 zpl_clear_inode(struct inode *ip)
120 {
121 fstrans_cookie_t cookie;
122
123 cookie = spl_fstrans_mark();
124 zfs_inactive(ip);
125 spl_fstrans_unmark(cookie);
126 }
127
128 static void
129 zpl_inode_delete(struct inode *ip)
130 {
131 truncate_setsize(ip, 0);
132 clear_inode(ip);
133 }
134 #endif /* HAVE_EVICT_INODE */
135
136 static void
137 zpl_put_super(struct super_block *sb)
138 {
139 fstrans_cookie_t cookie;
140 int error;
141
142 cookie = spl_fstrans_mark();
143 error = -zfs_umount(sb);
144 spl_fstrans_unmark(cookie);
145 ASSERT3S(error, <=, 0);
146 }
147
148 static int
149 zpl_sync_fs(struct super_block *sb, int wait)
150 {
151 fstrans_cookie_t cookie;
152 cred_t *cr = CRED();
153 int error;
154
155 crhold(cr);
156 cookie = spl_fstrans_mark();
157 error = -zfs_sync(sb, wait, cr);
158 spl_fstrans_unmark(cookie);
159 crfree(cr);
160 ASSERT3S(error, <=, 0);
161
162 return (error);
163 }
164
165 static int
166 zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
167 {
168 fstrans_cookie_t cookie;
169 int error;
170
171 cookie = spl_fstrans_mark();
172 error = -zfs_statvfs(dentry, statp);
173 spl_fstrans_unmark(cookie);
174 ASSERT3S(error, <=, 0);
175
176 return (error);
177 }
178
179 static int
180 zpl_remount_fs(struct super_block *sb, int *flags, char *data)
181 {
182 fstrans_cookie_t cookie;
183 int error;
184
185 cookie = spl_fstrans_mark();
186 error = -zfs_remount(sb, flags, data);
187 spl_fstrans_unmark(cookie);
188 ASSERT3S(error, <=, 0);
189
190 return (error);
191 }
192
193 static void
194 zpl_umount_begin(struct super_block *sb)
195 {
196 zfs_sb_t *zsb = sb->s_fs_info;
197 int count;
198
199 /*
200 * Best effort to unmount snapshots in .zfs/snapshot/. Normally this
201 * isn't required because snapshots have the MNT_SHRINKABLE flag set.
202 */
203 if (zsb->z_ctldir)
204 (void) zfsctl_unmount_snapshots(zsb, MNT_FORCE, &count);
205 }
206
207 /*
208 * ZFS specific features must be explicitly handled here, the VFS will
209 * automatically handled the following generic functionality.
210 *
211 * MNT_NOSUID,
212 * MNT_NODEV,
213 * MNT_NOEXEC,
214 * MNT_NOATIME,
215 * MNT_NODIRATIME,
216 * MNT_READONLY,
217 * MNT_STRICTATIME,
218 * MS_SYNCHRONOUS,
219 * MS_DIRSYNC,
220 * MS_MANDLOCK.
221 */
222 static int
223 __zpl_show_options(struct seq_file *seq, zfs_sb_t *zsb)
224 {
225 seq_printf(seq, ",%s", zsb->z_flags & ZSB_XATTR ? "xattr" : "noxattr");
226
227 #ifdef CONFIG_FS_POSIX_ACL
228 switch (zsb->z_acl_type) {
229 case ZFS_ACLTYPE_POSIXACL:
230 seq_puts(seq, ",posixacl");
231 break;
232 default:
233 seq_puts(seq, ",noacl");
234 break;
235 }
236 #endif /* CONFIG_FS_POSIX_ACL */
237
238 return (0);
239 }
240
241 #ifdef HAVE_SHOW_OPTIONS_WITH_DENTRY
242 static int
243 zpl_show_options(struct seq_file *seq, struct dentry *root)
244 {
245 return (__zpl_show_options(seq, root->d_sb->s_fs_info));
246 }
247 #else
248 static int
249 zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
250 {
251 return (__zpl_show_options(seq, vfsp->mnt_sb->s_fs_info));
252 }
253 #endif /* HAVE_SHOW_OPTIONS_WITH_DENTRY */
254
255 static int
256 zpl_fill_super(struct super_block *sb, void *data, int silent)
257 {
258 fstrans_cookie_t cookie;
259 int error;
260
261 cookie = spl_fstrans_mark();
262 error = -zfs_domount(sb, data, silent);
263 spl_fstrans_unmark(cookie);
264 ASSERT3S(error, <=, 0);
265
266 return (error);
267 }
268
269 #ifdef HAVE_MOUNT_NODEV
270 static struct dentry *
271 zpl_mount(struct file_system_type *fs_type, int flags,
272 const char *osname, void *data)
273 {
274 zpl_mount_data_t zmd = { osname, data };
275
276 return (mount_nodev(fs_type, flags, &zmd, zpl_fill_super));
277 }
278 #else
279 static int
280 zpl_get_sb(struct file_system_type *fs_type, int flags,
281 const char *osname, void *data, struct vfsmount *mnt)
282 {
283 zpl_mount_data_t zmd = { osname, data };
284
285 return (get_sb_nodev(fs_type, flags, &zmd, zpl_fill_super, mnt));
286 }
287 #endif /* HAVE_MOUNT_NODEV */
288
289 static void
290 zpl_kill_sb(struct super_block *sb)
291 {
292 zfs_preumount(sb);
293 kill_anon_super(sb);
294
295 #ifdef HAVE_S_INSTANCES_LIST_HEAD
296 sb->s_instances.next = &(zpl_fs_type.fs_supers);
297 #endif /* HAVE_S_INSTANCES_LIST_HEAD */
298 }
299
300 void
301 zpl_prune_sb(int64_t nr_to_scan, void *arg)
302 {
303 struct super_block *sb = (struct super_block *)arg;
304 int objects = 0;
305
306 (void) -zfs_sb_prune(sb, nr_to_scan, &objects);
307 }
308
309 #ifdef HAVE_NR_CACHED_OBJECTS
310 static int
311 zpl_nr_cached_objects(struct super_block *sb)
312 {
313 zfs_sb_t *zsb = sb->s_fs_info;
314 int nr;
315
316 mutex_enter(&zsb->z_znodes_lock);
317 nr = zsb->z_nr_znodes;
318 mutex_exit(&zsb->z_znodes_lock);
319
320 return (nr);
321 }
322 #endif /* HAVE_NR_CACHED_OBJECTS */
323
324 #ifdef HAVE_FREE_CACHED_OBJECTS
325 /*
326 * Attempt to evict some meta data from the cache. The ARC operates in
327 * terms of bytes while the Linux VFS uses objects. Now because this is
328 * just a best effort eviction and the exact values aren't critical so we
329 * extrapolate from an object count to a byte size using the znode_t size.
330 */
331 static void
332 zpl_free_cached_objects(struct super_block *sb, int nr_to_scan)
333 {
334 /* noop */
335 }
336 #endif /* HAVE_FREE_CACHED_OBJECTS */
337
338 const struct super_operations zpl_super_operations = {
339 .alloc_inode = zpl_inode_alloc,
340 .destroy_inode = zpl_inode_destroy,
341 .dirty_inode = zpl_dirty_inode,
342 .write_inode = NULL,
343 #ifdef HAVE_EVICT_INODE
344 .evict_inode = zpl_evict_inode,
345 #else
346 .drop_inode = zpl_drop_inode,
347 .clear_inode = zpl_clear_inode,
348 .delete_inode = zpl_inode_delete,
349 #endif /* HAVE_EVICT_INODE */
350 .put_super = zpl_put_super,
351 .sync_fs = zpl_sync_fs,
352 .statfs = zpl_statfs,
353 .remount_fs = zpl_remount_fs,
354 .umount_begin = zpl_umount_begin,
355 .show_options = zpl_show_options,
356 .show_stats = NULL,
357 #ifdef HAVE_NR_CACHED_OBJECTS
358 .nr_cached_objects = zpl_nr_cached_objects,
359 #endif /* HAVE_NR_CACHED_OBJECTS */
360 #ifdef HAVE_FREE_CACHED_OBJECTS
361 .free_cached_objects = zpl_free_cached_objects,
362 #endif /* HAVE_FREE_CACHED_OBJECTS */
363 };
364
365 struct file_system_type zpl_fs_type = {
366 .owner = THIS_MODULE,
367 .name = ZFS_DRIVER,
368 #ifdef HAVE_MOUNT_NODEV
369 .mount = zpl_mount,
370 #else
371 .get_sb = zpl_get_sb,
372 #endif /* HAVE_MOUNT_NODEV */
373 .kill_sb = zpl_kill_sb,
374 };