.. | .. |
---|
11 | 11 | #include "xfs_trans_resv.h" |
---|
12 | 12 | #include "xfs_sb.h" |
---|
13 | 13 | #include "xfs_mount.h" |
---|
14 | | -#include "xfs_da_format.h" |
---|
15 | 14 | #include "xfs_inode.h" |
---|
16 | 15 | #include "xfs_btree.h" |
---|
17 | 16 | #include "xfs_bmap.h" |
---|
18 | 17 | #include "xfs_alloc.h" |
---|
19 | | -#include "xfs_error.h" |
---|
20 | 18 | #include "xfs_fsops.h" |
---|
21 | 19 | #include "xfs_trans.h" |
---|
22 | 20 | #include "xfs_buf_item.h" |
---|
23 | 21 | #include "xfs_log.h" |
---|
24 | 22 | #include "xfs_log_priv.h" |
---|
25 | | -#include "xfs_da_btree.h" |
---|
26 | 23 | #include "xfs_dir2.h" |
---|
27 | 24 | #include "xfs_extfree_item.h" |
---|
28 | 25 | #include "xfs_mru_cache.h" |
---|
.. | .. |
---|
39 | 36 | #include "xfs_bmap_item.h" |
---|
40 | 37 | #include "xfs_reflink.h" |
---|
41 | 38 | |
---|
42 | | -#include <linux/namei.h> |
---|
43 | | -#include <linux/dax.h> |
---|
44 | | -#include <linux/init.h> |
---|
45 | | -#include <linux/slab.h> |
---|
46 | | -#include <linux/mount.h> |
---|
47 | | -#include <linux/mempool.h> |
---|
48 | | -#include <linux/writeback.h> |
---|
49 | | -#include <linux/kthread.h> |
---|
50 | | -#include <linux/freezer.h> |
---|
51 | | -#include <linux/parser.h> |
---|
| 39 | +#include <linux/magic.h> |
---|
| 40 | +#include <linux/fs_context.h> |
---|
| 41 | +#include <linux/fs_parser.h> |
---|
52 | 42 | |
---|
53 | 43 | static const struct super_operations xfs_super_operations; |
---|
54 | | -struct bio_set xfs_ioend_bioset; |
---|
55 | 44 | |
---|
56 | 45 | static struct kset *xfs_kset; /* top-level xfs sysfs dir */ |
---|
57 | 46 | #ifdef DEBUG |
---|
58 | 47 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ |
---|
59 | 48 | #endif |
---|
60 | 49 | |
---|
| 50 | +enum xfs_dax_mode { |
---|
| 51 | + XFS_DAX_INODE = 0, |
---|
| 52 | + XFS_DAX_ALWAYS = 1, |
---|
| 53 | + XFS_DAX_NEVER = 2, |
---|
| 54 | +}; |
---|
| 55 | + |
---|
| 56 | +static void |
---|
| 57 | +xfs_mount_set_dax_mode( |
---|
| 58 | + struct xfs_mount *mp, |
---|
| 59 | + enum xfs_dax_mode mode) |
---|
| 60 | +{ |
---|
| 61 | + switch (mode) { |
---|
| 62 | + case XFS_DAX_INODE: |
---|
| 63 | + mp->m_flags &= ~(XFS_MOUNT_DAX_ALWAYS | XFS_MOUNT_DAX_NEVER); |
---|
| 64 | + break; |
---|
| 65 | + case XFS_DAX_ALWAYS: |
---|
| 66 | + mp->m_flags |= XFS_MOUNT_DAX_ALWAYS; |
---|
| 67 | + mp->m_flags &= ~XFS_MOUNT_DAX_NEVER; |
---|
| 68 | + break; |
---|
| 69 | + case XFS_DAX_NEVER: |
---|
| 70 | + mp->m_flags |= XFS_MOUNT_DAX_NEVER; |
---|
| 71 | + mp->m_flags &= ~XFS_MOUNT_DAX_ALWAYS; |
---|
| 72 | + break; |
---|
| 73 | + } |
---|
| 74 | +} |
---|
| 75 | + |
---|
| 76 | +static const struct constant_table dax_param_enums[] = { |
---|
| 77 | + {"inode", XFS_DAX_INODE }, |
---|
| 78 | + {"always", XFS_DAX_ALWAYS }, |
---|
| 79 | + {"never", XFS_DAX_NEVER }, |
---|
| 80 | + {} |
---|
| 81 | +}; |
---|
| 82 | + |
---|
61 | 83 | /* |
---|
62 | 84 | * Table driven mount option parser. |
---|
63 | 85 | */ |
---|
64 | 86 | enum { |
---|
65 | | - Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize, |
---|
| 87 | + Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, |
---|
66 | 88 | Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, |
---|
67 | | - Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, |
---|
| 89 | + Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, |
---|
68 | 90 | Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep, |
---|
69 | 91 | Opt_noikeep, Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, |
---|
70 | 92 | Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, |
---|
71 | 93 | Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, |
---|
72 | 94 | Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, |
---|
73 | | - Opt_discard, Opt_nodiscard, Opt_dax, Opt_err, |
---|
| 95 | + Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, |
---|
74 | 96 | }; |
---|
75 | 97 | |
---|
76 | | -static const match_table_t tokens = { |
---|
77 | | - {Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */ |
---|
78 | | - {Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */ |
---|
79 | | - {Opt_logdev, "logdev=%s"}, /* log device */ |
---|
80 | | - {Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */ |
---|
81 | | - {Opt_biosize, "biosize=%u"}, /* log2 of preferred buffered io size */ |
---|
82 | | - {Opt_wsync, "wsync"}, /* safe-mode nfs compatible mount */ |
---|
83 | | - {Opt_noalign, "noalign"}, /* turn off stripe alignment */ |
---|
84 | | - {Opt_swalloc, "swalloc"}, /* turn on stripe width allocation */ |
---|
85 | | - {Opt_sunit, "sunit=%u"}, /* data volume stripe unit */ |
---|
86 | | - {Opt_swidth, "swidth=%u"}, /* data volume stripe width */ |
---|
87 | | - {Opt_nouuid, "nouuid"}, /* ignore filesystem UUID */ |
---|
88 | | - {Opt_mtpt, "mtpt"}, /* filesystem mount point */ |
---|
89 | | - {Opt_grpid, "grpid"}, /* group-ID from parent directory */ |
---|
90 | | - {Opt_nogrpid, "nogrpid"}, /* group-ID from current process */ |
---|
91 | | - {Opt_bsdgroups, "bsdgroups"}, /* group-ID from parent directory */ |
---|
92 | | - {Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */ |
---|
93 | | - {Opt_allocsize, "allocsize=%s"},/* preferred allocation size */ |
---|
94 | | - {Opt_norecovery,"norecovery"}, /* don't run XFS recovery */ |
---|
95 | | - {Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */ |
---|
96 | | - {Opt_inode32, "inode32"}, /* inode allocation limited to |
---|
97 | | - * XFS_MAXINUMBER_32 */ |
---|
98 | | - {Opt_ikeep, "ikeep"}, /* do not free empty inode clusters */ |
---|
99 | | - {Opt_noikeep, "noikeep"}, /* free empty inode clusters */ |
---|
100 | | - {Opt_largeio, "largeio"}, /* report large I/O sizes in stat() */ |
---|
101 | | - {Opt_nolargeio, "nolargeio"}, /* do not report large I/O sizes |
---|
102 | | - * in stat(). */ |
---|
103 | | - {Opt_attr2, "attr2"}, /* do use attr2 attribute format */ |
---|
104 | | - {Opt_noattr2, "noattr2"}, /* do not use attr2 attribute format */ |
---|
105 | | - {Opt_filestreams,"filestreams"},/* use filestreams allocator */ |
---|
106 | | - {Opt_quota, "quota"}, /* disk quotas (user) */ |
---|
107 | | - {Opt_noquota, "noquota"}, /* no quotas */ |
---|
108 | | - {Opt_usrquota, "usrquota"}, /* user quota enabled */ |
---|
109 | | - {Opt_grpquota, "grpquota"}, /* group quota enabled */ |
---|
110 | | - {Opt_prjquota, "prjquota"}, /* project quota enabled */ |
---|
111 | | - {Opt_uquota, "uquota"}, /* user quota (IRIX variant) */ |
---|
112 | | - {Opt_gquota, "gquota"}, /* group quota (IRIX variant) */ |
---|
113 | | - {Opt_pquota, "pquota"}, /* project quota (IRIX variant) */ |
---|
114 | | - {Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */ |
---|
115 | | - {Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */ |
---|
116 | | - {Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */ |
---|
117 | | - {Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */ |
---|
118 | | - {Opt_discard, "discard"}, /* Discard unused blocks */ |
---|
119 | | - {Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */ |
---|
120 | | - {Opt_dax, "dax"}, /* Enable direct access to bdev pages */ |
---|
121 | | - {Opt_err, NULL}, |
---|
| 98 | +static const struct fs_parameter_spec xfs_fs_parameters[] = { |
---|
| 99 | + fsparam_u32("logbufs", Opt_logbufs), |
---|
| 100 | + fsparam_string("logbsize", Opt_logbsize), |
---|
| 101 | + fsparam_string("logdev", Opt_logdev), |
---|
| 102 | + fsparam_string("rtdev", Opt_rtdev), |
---|
| 103 | + fsparam_flag("wsync", Opt_wsync), |
---|
| 104 | + fsparam_flag("noalign", Opt_noalign), |
---|
| 105 | + fsparam_flag("swalloc", Opt_swalloc), |
---|
| 106 | + fsparam_u32("sunit", Opt_sunit), |
---|
| 107 | + fsparam_u32("swidth", Opt_swidth), |
---|
| 108 | + fsparam_flag("nouuid", Opt_nouuid), |
---|
| 109 | + fsparam_flag("grpid", Opt_grpid), |
---|
| 110 | + fsparam_flag("nogrpid", Opt_nogrpid), |
---|
| 111 | + fsparam_flag("bsdgroups", Opt_bsdgroups), |
---|
| 112 | + fsparam_flag("sysvgroups", Opt_sysvgroups), |
---|
| 113 | + fsparam_string("allocsize", Opt_allocsize), |
---|
| 114 | + fsparam_flag("norecovery", Opt_norecovery), |
---|
| 115 | + fsparam_flag("inode64", Opt_inode64), |
---|
| 116 | + fsparam_flag("inode32", Opt_inode32), |
---|
| 117 | + fsparam_flag("ikeep", Opt_ikeep), |
---|
| 118 | + fsparam_flag("noikeep", Opt_noikeep), |
---|
| 119 | + fsparam_flag("largeio", Opt_largeio), |
---|
| 120 | + fsparam_flag("nolargeio", Opt_nolargeio), |
---|
| 121 | + fsparam_flag("attr2", Opt_attr2), |
---|
| 122 | + fsparam_flag("noattr2", Opt_noattr2), |
---|
| 123 | + fsparam_flag("filestreams", Opt_filestreams), |
---|
| 124 | + fsparam_flag("quota", Opt_quota), |
---|
| 125 | + fsparam_flag("noquota", Opt_noquota), |
---|
| 126 | + fsparam_flag("usrquota", Opt_usrquota), |
---|
| 127 | + fsparam_flag("grpquota", Opt_grpquota), |
---|
| 128 | + fsparam_flag("prjquota", Opt_prjquota), |
---|
| 129 | + fsparam_flag("uquota", Opt_uquota), |
---|
| 130 | + fsparam_flag("gquota", Opt_gquota), |
---|
| 131 | + fsparam_flag("pquota", Opt_pquota), |
---|
| 132 | + fsparam_flag("uqnoenforce", Opt_uqnoenforce), |
---|
| 133 | + fsparam_flag("gqnoenforce", Opt_gqnoenforce), |
---|
| 134 | + fsparam_flag("pqnoenforce", Opt_pqnoenforce), |
---|
| 135 | + fsparam_flag("qnoenforce", Opt_qnoenforce), |
---|
| 136 | + fsparam_flag("discard", Opt_discard), |
---|
| 137 | + fsparam_flag("nodiscard", Opt_nodiscard), |
---|
| 138 | + fsparam_flag("dax", Opt_dax), |
---|
| 139 | + fsparam_enum("dax", Opt_dax_enum, dax_param_enums), |
---|
| 140 | + {} |
---|
122 | 141 | }; |
---|
123 | | - |
---|
124 | | - |
---|
125 | | -STATIC int |
---|
126 | | -suffix_kstrtoint(const substring_t *s, unsigned int base, int *res) |
---|
127 | | -{ |
---|
128 | | - int last, shift_left_factor = 0, _res; |
---|
129 | | - char *value; |
---|
130 | | - int ret = 0; |
---|
131 | | - |
---|
132 | | - value = match_strdup(s); |
---|
133 | | - if (!value) |
---|
134 | | - return -ENOMEM; |
---|
135 | | - |
---|
136 | | - last = strlen(value) - 1; |
---|
137 | | - if (value[last] == 'K' || value[last] == 'k') { |
---|
138 | | - shift_left_factor = 10; |
---|
139 | | - value[last] = '\0'; |
---|
140 | | - } |
---|
141 | | - if (value[last] == 'M' || value[last] == 'm') { |
---|
142 | | - shift_left_factor = 20; |
---|
143 | | - value[last] = '\0'; |
---|
144 | | - } |
---|
145 | | - if (value[last] == 'G' || value[last] == 'g') { |
---|
146 | | - shift_left_factor = 30; |
---|
147 | | - value[last] = '\0'; |
---|
148 | | - } |
---|
149 | | - |
---|
150 | | - if (kstrtoint(value, base, &_res)) |
---|
151 | | - ret = -EINVAL; |
---|
152 | | - kfree(value); |
---|
153 | | - *res = _res << shift_left_factor; |
---|
154 | | - return ret; |
---|
155 | | -} |
---|
156 | | - |
---|
157 | | -/* |
---|
158 | | - * This function fills in xfs_mount_t fields based on mount args. |
---|
159 | | - * Note: the superblock has _not_ yet been read in. |
---|
160 | | - * |
---|
161 | | - * Note that this function leaks the various device name allocations on |
---|
162 | | - * failure. The caller takes care of them. |
---|
163 | | - * |
---|
164 | | - * *sb is const because this is also used to test options on the remount |
---|
165 | | - * path, and we don't want this to have any side effects at remount time. |
---|
166 | | - * Today this function does not change *sb, but just to future-proof... |
---|
167 | | - */ |
---|
168 | | -STATIC int |
---|
169 | | -xfs_parseargs( |
---|
170 | | - struct xfs_mount *mp, |
---|
171 | | - char *options) |
---|
172 | | -{ |
---|
173 | | - const struct super_block *sb = mp->m_super; |
---|
174 | | - char *p; |
---|
175 | | - substring_t args[MAX_OPT_ARGS]; |
---|
176 | | - int dsunit = 0; |
---|
177 | | - int dswidth = 0; |
---|
178 | | - int iosize = 0; |
---|
179 | | - uint8_t iosizelog = 0; |
---|
180 | | - |
---|
181 | | - /* |
---|
182 | | - * set up the mount name first so all the errors will refer to the |
---|
183 | | - * correct device. |
---|
184 | | - */ |
---|
185 | | - mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); |
---|
186 | | - if (!mp->m_fsname) |
---|
187 | | - return -ENOMEM; |
---|
188 | | - mp->m_fsname_len = strlen(mp->m_fsname) + 1; |
---|
189 | | - |
---|
190 | | - /* |
---|
191 | | - * Copy binary VFS mount flags we are interested in. |
---|
192 | | - */ |
---|
193 | | - if (sb_rdonly(sb)) |
---|
194 | | - mp->m_flags |= XFS_MOUNT_RDONLY; |
---|
195 | | - if (sb->s_flags & SB_DIRSYNC) |
---|
196 | | - mp->m_flags |= XFS_MOUNT_DIRSYNC; |
---|
197 | | - if (sb->s_flags & SB_SYNCHRONOUS) |
---|
198 | | - mp->m_flags |= XFS_MOUNT_WSYNC; |
---|
199 | | - |
---|
200 | | - /* |
---|
201 | | - * Set some default flags that could be cleared by the mount option |
---|
202 | | - * parsing. |
---|
203 | | - */ |
---|
204 | | - mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
---|
205 | | - |
---|
206 | | - /* |
---|
207 | | - * These can be overridden by the mount option parsing. |
---|
208 | | - */ |
---|
209 | | - mp->m_logbufs = -1; |
---|
210 | | - mp->m_logbsize = -1; |
---|
211 | | - |
---|
212 | | - if (!options) |
---|
213 | | - goto done; |
---|
214 | | - |
---|
215 | | - while ((p = strsep(&options, ",")) != NULL) { |
---|
216 | | - int token; |
---|
217 | | - |
---|
218 | | - if (!*p) |
---|
219 | | - continue; |
---|
220 | | - |
---|
221 | | - token = match_token(p, tokens, args); |
---|
222 | | - switch (token) { |
---|
223 | | - case Opt_logbufs: |
---|
224 | | - if (match_int(args, &mp->m_logbufs)) |
---|
225 | | - return -EINVAL; |
---|
226 | | - break; |
---|
227 | | - case Opt_logbsize: |
---|
228 | | - if (suffix_kstrtoint(args, 10, &mp->m_logbsize)) |
---|
229 | | - return -EINVAL; |
---|
230 | | - break; |
---|
231 | | - case Opt_logdev: |
---|
232 | | - kfree(mp->m_logname); |
---|
233 | | - mp->m_logname = match_strdup(args); |
---|
234 | | - if (!mp->m_logname) |
---|
235 | | - return -ENOMEM; |
---|
236 | | - break; |
---|
237 | | - case Opt_mtpt: |
---|
238 | | - xfs_warn(mp, "%s option not allowed on this system", p); |
---|
239 | | - return -EINVAL; |
---|
240 | | - case Opt_rtdev: |
---|
241 | | - kfree(mp->m_rtname); |
---|
242 | | - mp->m_rtname = match_strdup(args); |
---|
243 | | - if (!mp->m_rtname) |
---|
244 | | - return -ENOMEM; |
---|
245 | | - break; |
---|
246 | | - case Opt_allocsize: |
---|
247 | | - case Opt_biosize: |
---|
248 | | - if (suffix_kstrtoint(args, 10, &iosize)) |
---|
249 | | - return -EINVAL; |
---|
250 | | - iosizelog = ffs(iosize) - 1; |
---|
251 | | - break; |
---|
252 | | - case Opt_grpid: |
---|
253 | | - case Opt_bsdgroups: |
---|
254 | | - mp->m_flags |= XFS_MOUNT_GRPID; |
---|
255 | | - break; |
---|
256 | | - case Opt_nogrpid: |
---|
257 | | - case Opt_sysvgroups: |
---|
258 | | - mp->m_flags &= ~XFS_MOUNT_GRPID; |
---|
259 | | - break; |
---|
260 | | - case Opt_wsync: |
---|
261 | | - mp->m_flags |= XFS_MOUNT_WSYNC; |
---|
262 | | - break; |
---|
263 | | - case Opt_norecovery: |
---|
264 | | - mp->m_flags |= XFS_MOUNT_NORECOVERY; |
---|
265 | | - break; |
---|
266 | | - case Opt_noalign: |
---|
267 | | - mp->m_flags |= XFS_MOUNT_NOALIGN; |
---|
268 | | - break; |
---|
269 | | - case Opt_swalloc: |
---|
270 | | - mp->m_flags |= XFS_MOUNT_SWALLOC; |
---|
271 | | - break; |
---|
272 | | - case Opt_sunit: |
---|
273 | | - if (match_int(args, &dsunit)) |
---|
274 | | - return -EINVAL; |
---|
275 | | - break; |
---|
276 | | - case Opt_swidth: |
---|
277 | | - if (match_int(args, &dswidth)) |
---|
278 | | - return -EINVAL; |
---|
279 | | - break; |
---|
280 | | - case Opt_inode32: |
---|
281 | | - mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
---|
282 | | - break; |
---|
283 | | - case Opt_inode64: |
---|
284 | | - mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
---|
285 | | - break; |
---|
286 | | - case Opt_nouuid: |
---|
287 | | - mp->m_flags |= XFS_MOUNT_NOUUID; |
---|
288 | | - break; |
---|
289 | | - case Opt_ikeep: |
---|
290 | | - mp->m_flags |= XFS_MOUNT_IKEEP; |
---|
291 | | - break; |
---|
292 | | - case Opt_noikeep: |
---|
293 | | - mp->m_flags &= ~XFS_MOUNT_IKEEP; |
---|
294 | | - break; |
---|
295 | | - case Opt_largeio: |
---|
296 | | - mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
---|
297 | | - break; |
---|
298 | | - case Opt_nolargeio: |
---|
299 | | - mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
---|
300 | | - break; |
---|
301 | | - case Opt_attr2: |
---|
302 | | - mp->m_flags |= XFS_MOUNT_ATTR2; |
---|
303 | | - break; |
---|
304 | | - case Opt_noattr2: |
---|
305 | | - mp->m_flags &= ~XFS_MOUNT_ATTR2; |
---|
306 | | - mp->m_flags |= XFS_MOUNT_NOATTR2; |
---|
307 | | - break; |
---|
308 | | - case Opt_filestreams: |
---|
309 | | - mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
---|
310 | | - break; |
---|
311 | | - case Opt_noquota: |
---|
312 | | - mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; |
---|
313 | | - mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; |
---|
314 | | - mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; |
---|
315 | | - break; |
---|
316 | | - case Opt_quota: |
---|
317 | | - case Opt_uquota: |
---|
318 | | - case Opt_usrquota: |
---|
319 | | - mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
---|
320 | | - XFS_UQUOTA_ENFD); |
---|
321 | | - break; |
---|
322 | | - case Opt_qnoenforce: |
---|
323 | | - case Opt_uqnoenforce: |
---|
324 | | - mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
---|
325 | | - mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
---|
326 | | - break; |
---|
327 | | - case Opt_pquota: |
---|
328 | | - case Opt_prjquota: |
---|
329 | | - mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
---|
330 | | - XFS_PQUOTA_ENFD); |
---|
331 | | - break; |
---|
332 | | - case Opt_pqnoenforce: |
---|
333 | | - mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
---|
334 | | - mp->m_qflags &= ~XFS_PQUOTA_ENFD; |
---|
335 | | - break; |
---|
336 | | - case Opt_gquota: |
---|
337 | | - case Opt_grpquota: |
---|
338 | | - mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
---|
339 | | - XFS_GQUOTA_ENFD); |
---|
340 | | - break; |
---|
341 | | - case Opt_gqnoenforce: |
---|
342 | | - mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
---|
343 | | - mp->m_qflags &= ~XFS_GQUOTA_ENFD; |
---|
344 | | - break; |
---|
345 | | - case Opt_discard: |
---|
346 | | - mp->m_flags |= XFS_MOUNT_DISCARD; |
---|
347 | | - break; |
---|
348 | | - case Opt_nodiscard: |
---|
349 | | - mp->m_flags &= ~XFS_MOUNT_DISCARD; |
---|
350 | | - break; |
---|
351 | | -#ifdef CONFIG_FS_DAX |
---|
352 | | - case Opt_dax: |
---|
353 | | - mp->m_flags |= XFS_MOUNT_DAX; |
---|
354 | | - break; |
---|
355 | | -#endif |
---|
356 | | - default: |
---|
357 | | - xfs_warn(mp, "unknown mount option [%s].", p); |
---|
358 | | - return -EINVAL; |
---|
359 | | - } |
---|
360 | | - } |
---|
361 | | - |
---|
362 | | - /* |
---|
363 | | - * no recovery flag requires a read-only mount |
---|
364 | | - */ |
---|
365 | | - if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && |
---|
366 | | - !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
---|
367 | | - xfs_warn(mp, "no-recovery mounts must be read-only."); |
---|
368 | | - return -EINVAL; |
---|
369 | | - } |
---|
370 | | - |
---|
371 | | - if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { |
---|
372 | | - xfs_warn(mp, |
---|
373 | | - "sunit and swidth options incompatible with the noalign option"); |
---|
374 | | - return -EINVAL; |
---|
375 | | - } |
---|
376 | | - |
---|
377 | | -#ifndef CONFIG_XFS_QUOTA |
---|
378 | | - if (XFS_IS_QUOTA_RUNNING(mp)) { |
---|
379 | | - xfs_warn(mp, "quota support not available in this kernel."); |
---|
380 | | - return -EINVAL; |
---|
381 | | - } |
---|
382 | | -#endif |
---|
383 | | - |
---|
384 | | - if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
---|
385 | | - xfs_warn(mp, "sunit and swidth must be specified together"); |
---|
386 | | - return -EINVAL; |
---|
387 | | - } |
---|
388 | | - |
---|
389 | | - if (dsunit && (dswidth % dsunit != 0)) { |
---|
390 | | - xfs_warn(mp, |
---|
391 | | - "stripe width (%d) must be a multiple of the stripe unit (%d)", |
---|
392 | | - dswidth, dsunit); |
---|
393 | | - return -EINVAL; |
---|
394 | | - } |
---|
395 | | - |
---|
396 | | -done: |
---|
397 | | - if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) { |
---|
398 | | - /* |
---|
399 | | - * At this point the superblock has not been read |
---|
400 | | - * in, therefore we do not know the block size. |
---|
401 | | - * Before the mount call ends we will convert |
---|
402 | | - * these to FSBs. |
---|
403 | | - */ |
---|
404 | | - mp->m_dalign = dsunit; |
---|
405 | | - mp->m_swidth = dswidth; |
---|
406 | | - } |
---|
407 | | - |
---|
408 | | - if (mp->m_logbufs != -1 && |
---|
409 | | - mp->m_logbufs != 0 && |
---|
410 | | - (mp->m_logbufs < XLOG_MIN_ICLOGS || |
---|
411 | | - mp->m_logbufs > XLOG_MAX_ICLOGS)) { |
---|
412 | | - xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", |
---|
413 | | - mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); |
---|
414 | | - return -EINVAL; |
---|
415 | | - } |
---|
416 | | - if (mp->m_logbsize != -1 && |
---|
417 | | - mp->m_logbsize != 0 && |
---|
418 | | - (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || |
---|
419 | | - mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || |
---|
420 | | - !is_power_of_2(mp->m_logbsize))) { |
---|
421 | | - xfs_warn(mp, |
---|
422 | | - "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", |
---|
423 | | - mp->m_logbsize); |
---|
424 | | - return -EINVAL; |
---|
425 | | - } |
---|
426 | | - |
---|
427 | | - if (iosizelog) { |
---|
428 | | - if (iosizelog > XFS_MAX_IO_LOG || |
---|
429 | | - iosizelog < XFS_MIN_IO_LOG) { |
---|
430 | | - xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", |
---|
431 | | - iosizelog, XFS_MIN_IO_LOG, |
---|
432 | | - XFS_MAX_IO_LOG); |
---|
433 | | - return -EINVAL; |
---|
434 | | - } |
---|
435 | | - |
---|
436 | | - mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; |
---|
437 | | - mp->m_readio_log = iosizelog; |
---|
438 | | - mp->m_writeio_log = iosizelog; |
---|
439 | | - } |
---|
440 | | - |
---|
441 | | - return 0; |
---|
442 | | -} |
---|
443 | 142 | |
---|
444 | 143 | struct proc_xfs_info { |
---|
445 | 144 | uint64_t flag; |
---|
446 | 145 | char *str; |
---|
447 | 146 | }; |
---|
448 | 147 | |
---|
449 | | -STATIC int |
---|
450 | | -xfs_showargs( |
---|
451 | | - struct xfs_mount *mp, |
---|
452 | | - struct seq_file *m) |
---|
| 148 | +static int |
---|
| 149 | +xfs_fs_show_options( |
---|
| 150 | + struct seq_file *m, |
---|
| 151 | + struct dentry *root) |
---|
453 | 152 | { |
---|
454 | 153 | static struct proc_xfs_info xfs_info_set[] = { |
---|
455 | 154 | /* the few simple ones we can get from the mount struct */ |
---|
.. | .. |
---|
463 | 162 | { XFS_MOUNT_FILESTREAMS, ",filestreams" }, |
---|
464 | 163 | { XFS_MOUNT_GRPID, ",grpid" }, |
---|
465 | 164 | { XFS_MOUNT_DISCARD, ",discard" }, |
---|
466 | | - { XFS_MOUNT_SMALL_INUMS, ",inode32" }, |
---|
467 | | - { XFS_MOUNT_DAX, ",dax" }, |
---|
| 165 | + { XFS_MOUNT_LARGEIO, ",largeio" }, |
---|
| 166 | + { XFS_MOUNT_DAX_ALWAYS, ",dax=always" }, |
---|
| 167 | + { XFS_MOUNT_DAX_NEVER, ",dax=never" }, |
---|
468 | 168 | { 0, NULL } |
---|
469 | 169 | }; |
---|
470 | | - static struct proc_xfs_info xfs_info_unset[] = { |
---|
471 | | - /* the few simple ones we can get from the mount struct */ |
---|
472 | | - { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" }, |
---|
473 | | - { XFS_MOUNT_SMALL_INUMS, ",inode64" }, |
---|
474 | | - { 0, NULL } |
---|
475 | | - }; |
---|
| 170 | + struct xfs_mount *mp = XFS_M(root->d_sb); |
---|
476 | 171 | struct proc_xfs_info *xfs_infop; |
---|
477 | 172 | |
---|
478 | 173 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { |
---|
479 | 174 | if (mp->m_flags & xfs_infop->flag) |
---|
480 | 175 | seq_puts(m, xfs_infop->str); |
---|
481 | 176 | } |
---|
482 | | - for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { |
---|
483 | | - if (!(mp->m_flags & xfs_infop->flag)) |
---|
484 | | - seq_puts(m, xfs_infop->str); |
---|
485 | | - } |
---|
486 | 177 | |
---|
487 | | - if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
---|
| 178 | + seq_printf(m, ",inode%d", |
---|
| 179 | + (mp->m_flags & XFS_MOUNT_SMALL_INUMS) ? 32 : 64); |
---|
| 180 | + |
---|
| 181 | + if (mp->m_flags & XFS_MOUNT_ALLOCSIZE) |
---|
488 | 182 | seq_printf(m, ",allocsize=%dk", |
---|
489 | | - (int)(1 << mp->m_writeio_log) >> 10); |
---|
| 183 | + (1 << mp->m_allocsize_log) >> 10); |
---|
490 | 184 | |
---|
491 | 185 | if (mp->m_logbufs > 0) |
---|
492 | 186 | seq_printf(m, ",logbufs=%d", mp->m_logbufs); |
---|
.. | .. |
---|
505 | 199 | seq_printf(m, ",swidth=%d", |
---|
506 | 200 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); |
---|
507 | 201 | |
---|
508 | | - if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) |
---|
509 | | - seq_puts(m, ",usrquota"); |
---|
510 | | - else if (mp->m_qflags & XFS_UQUOTA_ACCT) |
---|
511 | | - seq_puts(m, ",uqnoenforce"); |
---|
| 202 | + if (mp->m_qflags & XFS_UQUOTA_ACCT) { |
---|
| 203 | + if (mp->m_qflags & XFS_UQUOTA_ENFD) |
---|
| 204 | + seq_puts(m, ",usrquota"); |
---|
| 205 | + else |
---|
| 206 | + seq_puts(m, ",uqnoenforce"); |
---|
| 207 | + } |
---|
512 | 208 | |
---|
513 | 209 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { |
---|
514 | 210 | if (mp->m_qflags & XFS_PQUOTA_ENFD) |
---|
.. | .. |
---|
527 | 223 | seq_puts(m, ",noquota"); |
---|
528 | 224 | |
---|
529 | 225 | return 0; |
---|
530 | | -} |
---|
531 | | -static uint64_t |
---|
532 | | -xfs_max_file_offset( |
---|
533 | | - unsigned int blockshift) |
---|
534 | | -{ |
---|
535 | | - unsigned int pagefactor = 1; |
---|
536 | | - unsigned int bitshift = BITS_PER_LONG - 1; |
---|
537 | | - |
---|
538 | | - /* Figure out maximum filesize, on Linux this can depend on |
---|
539 | | - * the filesystem blocksize (on 32 bit platforms). |
---|
540 | | - * __block_write_begin does this in an [unsigned] long... |
---|
541 | | - * page->index << (PAGE_SHIFT - bbits) |
---|
542 | | - * So, for page sized blocks (4K on 32 bit platforms), |
---|
543 | | - * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is |
---|
544 | | - * (((u64)PAGE_SIZE << (BITS_PER_LONG-1))-1) |
---|
545 | | - * but for smaller blocksizes it is less (bbits = log2 bsize). |
---|
546 | | - * Note1: get_block_t takes a long (implicit cast from above) |
---|
547 | | - * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch |
---|
548 | | - * can optionally convert the [unsigned] long from above into |
---|
549 | | - * an [unsigned] long long. |
---|
550 | | - */ |
---|
551 | | - |
---|
552 | | -#if BITS_PER_LONG == 32 |
---|
553 | | -# if defined(CONFIG_LBDAF) |
---|
554 | | - ASSERT(sizeof(sector_t) == 8); |
---|
555 | | - pagefactor = PAGE_SIZE; |
---|
556 | | - bitshift = BITS_PER_LONG; |
---|
557 | | -# else |
---|
558 | | - pagefactor = PAGE_SIZE >> (PAGE_SHIFT - blockshift); |
---|
559 | | -# endif |
---|
560 | | -#endif |
---|
561 | | - |
---|
562 | | - return (((uint64_t)pagefactor) << bitshift) - 1; |
---|
563 | 226 | } |
---|
564 | 227 | |
---|
565 | 228 | /* |
---|
.. | .. |
---|
593 | 256 | * Calculate how much should be reserved for inodes to meet |
---|
594 | 257 | * the max inode percentage. Used only for inode32. |
---|
595 | 258 | */ |
---|
596 | | - if (mp->m_maxicount) { |
---|
| 259 | + if (M_IGEO(mp)->maxicount) { |
---|
597 | 260 | uint64_t icount; |
---|
598 | 261 | |
---|
599 | 262 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; |
---|
.. | .. |
---|
606 | 269 | } |
---|
607 | 270 | |
---|
608 | 271 | /* Get the last possible inode in the filesystem */ |
---|
609 | | - agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); |
---|
| 272 | + agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1); |
---|
610 | 273 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); |
---|
611 | 274 | |
---|
612 | 275 | /* |
---|
.. | .. |
---|
679 | 342 | xfs_blkdev_issue_flush( |
---|
680 | 343 | xfs_buftarg_t *buftarg) |
---|
681 | 344 | { |
---|
682 | | - blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL); |
---|
| 345 | + blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS); |
---|
683 | 346 | } |
---|
684 | 347 | |
---|
685 | 348 | STATIC void |
---|
.. | .. |
---|
832 | 495 | struct xfs_mount *mp) |
---|
833 | 496 | { |
---|
834 | 497 | mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s", |
---|
835 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_fsname); |
---|
| 498 | + WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_super->s_id); |
---|
836 | 499 | if (!mp->m_buf_workqueue) |
---|
837 | 500 | goto out; |
---|
838 | 501 | |
---|
839 | | - mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", |
---|
840 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); |
---|
841 | | - if (!mp->m_data_workqueue) |
---|
| 502 | + mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", |
---|
| 503 | + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); |
---|
| 504 | + if (!mp->m_unwritten_workqueue) |
---|
842 | 505 | goto out_destroy_buf; |
---|
843 | 506 | |
---|
844 | | - mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", |
---|
845 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); |
---|
846 | | - if (!mp->m_unwritten_workqueue) |
---|
847 | | - goto out_destroy_data_iodone_queue; |
---|
848 | | - |
---|
849 | 507 | mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", |
---|
850 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); |
---|
| 508 | + WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND, |
---|
| 509 | + 0, mp->m_super->s_id); |
---|
851 | 510 | if (!mp->m_cil_workqueue) |
---|
852 | 511 | goto out_destroy_unwritten; |
---|
853 | 512 | |
---|
854 | 513 | mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s", |
---|
855 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); |
---|
| 514 | + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); |
---|
856 | 515 | if (!mp->m_reclaim_workqueue) |
---|
857 | 516 | goto out_destroy_cil; |
---|
858 | 517 | |
---|
859 | | - mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", |
---|
860 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE|WQ_HIGHPRI, 0, |
---|
861 | | - mp->m_fsname); |
---|
862 | | - if (!mp->m_log_workqueue) |
---|
| 518 | + mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", |
---|
| 519 | + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); |
---|
| 520 | + if (!mp->m_eofblocks_workqueue) |
---|
863 | 521 | goto out_destroy_reclaim; |
---|
864 | 522 | |
---|
865 | | - mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", |
---|
866 | | - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); |
---|
867 | | - if (!mp->m_eofblocks_workqueue) |
---|
868 | | - goto out_destroy_log; |
---|
869 | | - |
---|
870 | 523 | mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", WQ_FREEZABLE, 0, |
---|
871 | | - mp->m_fsname); |
---|
| 524 | + mp->m_super->s_id); |
---|
872 | 525 | if (!mp->m_sync_workqueue) |
---|
873 | 526 | goto out_destroy_eofb; |
---|
874 | 527 | |
---|
.. | .. |
---|
876 | 529 | |
---|
877 | 530 | out_destroy_eofb: |
---|
878 | 531 | destroy_workqueue(mp->m_eofblocks_workqueue); |
---|
879 | | -out_destroy_log: |
---|
880 | | - destroy_workqueue(mp->m_log_workqueue); |
---|
881 | 532 | out_destroy_reclaim: |
---|
882 | 533 | destroy_workqueue(mp->m_reclaim_workqueue); |
---|
883 | 534 | out_destroy_cil: |
---|
884 | 535 | destroy_workqueue(mp->m_cil_workqueue); |
---|
885 | 536 | out_destroy_unwritten: |
---|
886 | 537 | destroy_workqueue(mp->m_unwritten_workqueue); |
---|
887 | | -out_destroy_data_iodone_queue: |
---|
888 | | - destroy_workqueue(mp->m_data_workqueue); |
---|
889 | 538 | out_destroy_buf: |
---|
890 | 539 | destroy_workqueue(mp->m_buf_workqueue); |
---|
891 | 540 | out: |
---|
.. | .. |
---|
898 | 547 | { |
---|
899 | 548 | destroy_workqueue(mp->m_sync_workqueue); |
---|
900 | 549 | destroy_workqueue(mp->m_eofblocks_workqueue); |
---|
901 | | - destroy_workqueue(mp->m_log_workqueue); |
---|
902 | 550 | destroy_workqueue(mp->m_reclaim_workqueue); |
---|
903 | 551 | destroy_workqueue(mp->m_cil_workqueue); |
---|
904 | | - destroy_workqueue(mp->m_data_workqueue); |
---|
905 | 552 | destroy_workqueue(mp->m_unwritten_workqueue); |
---|
906 | 553 | destroy_workqueue(mp->m_buf_workqueue); |
---|
| 554 | +} |
---|
| 555 | + |
---|
| 556 | +static void |
---|
| 557 | +xfs_flush_inodes_worker( |
---|
| 558 | + struct work_struct *work) |
---|
| 559 | +{ |
---|
| 560 | + struct xfs_mount *mp = container_of(work, struct xfs_mount, |
---|
| 561 | + m_flush_inodes_work); |
---|
| 562 | + struct super_block *sb = mp->m_super; |
---|
| 563 | + |
---|
| 564 | + if (down_read_trylock(&sb->s_umount)) { |
---|
| 565 | + sync_inodes_sb(sb); |
---|
| 566 | + up_read(&sb->s_umount); |
---|
| 567 | + } |
---|
907 | 568 | } |
---|
908 | 569 | |
---|
909 | 570 | /* |
---|
.. | .. |
---|
916 | 577 | xfs_flush_inodes( |
---|
917 | 578 | struct xfs_mount *mp) |
---|
918 | 579 | { |
---|
919 | | - struct super_block *sb = mp->m_super; |
---|
| 580 | + /* |
---|
| 581 | + * If flush_work() returns true then that means we waited for a flush |
---|
| 582 | + * which was already in progress. Don't bother running another scan. |
---|
| 583 | + */ |
---|
| 584 | + if (flush_work(&mp->m_flush_inodes_work)) |
---|
| 585 | + return; |
---|
920 | 586 | |
---|
921 | | - if (down_read_trylock(&sb->s_umount)) { |
---|
922 | | - sync_inodes_sb(sb); |
---|
923 | | - up_read(&sb->s_umount); |
---|
924 | | - } |
---|
| 587 | + queue_work(mp->m_sync_workqueue, &mp->m_flush_inodes_work); |
---|
| 588 | + flush_work(&mp->m_flush_inodes_work); |
---|
925 | 589 | } |
---|
926 | 590 | |
---|
927 | 591 | /* Catch misguided souls that try to use this interface on XFS */ |
---|
.. | .. |
---|
932 | 596 | BUG(); |
---|
933 | 597 | return NULL; |
---|
934 | 598 | } |
---|
| 599 | + |
---|
| 600 | +#ifdef DEBUG |
---|
| 601 | +static void |
---|
| 602 | +xfs_check_delalloc( |
---|
| 603 | + struct xfs_inode *ip, |
---|
| 604 | + int whichfork) |
---|
| 605 | +{ |
---|
| 606 | + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); |
---|
| 607 | + struct xfs_bmbt_irec got; |
---|
| 608 | + struct xfs_iext_cursor icur; |
---|
| 609 | + |
---|
| 610 | + if (!ifp || !xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got)) |
---|
| 611 | + return; |
---|
| 612 | + do { |
---|
| 613 | + if (isnullstartblock(got.br_startblock)) { |
---|
| 614 | + xfs_warn(ip->i_mount, |
---|
| 615 | + "ino %llx %s fork has delalloc extent at [0x%llx:0x%llx]", |
---|
| 616 | + ip->i_ino, |
---|
| 617 | + whichfork == XFS_DATA_FORK ? "data" : "cow", |
---|
| 618 | + got.br_startoff, got.br_blockcount); |
---|
| 619 | + } |
---|
| 620 | + } while (xfs_iext_next_extent(ifp, &icur, &got)); |
---|
| 621 | +} |
---|
| 622 | +#else |
---|
| 623 | +#define xfs_check_delalloc(ip, whichfork) do { } while (0) |
---|
| 624 | +#endif |
---|
935 | 625 | |
---|
936 | 626 | /* |
---|
937 | 627 | * Now that the generic code is guaranteed not to be accessing |
---|
.. | .. |
---|
951 | 641 | |
---|
952 | 642 | xfs_inactive(ip); |
---|
953 | 643 | |
---|
954 | | - ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
---|
| 644 | + if (!XFS_FORCED_SHUTDOWN(ip->i_mount) && ip->i_delayed_blks) { |
---|
| 645 | + xfs_check_delalloc(ip, XFS_DATA_FORK); |
---|
| 646 | + xfs_check_delalloc(ip, XFS_COW_FORK); |
---|
| 647 | + ASSERT(0); |
---|
| 648 | + } |
---|
| 649 | + |
---|
955 | 650 | XFS_STATS_INC(ip->i_mount, vn_reclaim); |
---|
956 | 651 | |
---|
957 | 652 | /* |
---|
.. | .. |
---|
961 | 656 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); |
---|
962 | 657 | |
---|
963 | 658 | /* |
---|
964 | | - * We always use background reclaim here because even if the |
---|
965 | | - * inode is clean, it still may be under IO and hence we have |
---|
966 | | - * to take the flush lock. The background reclaim path handles |
---|
967 | | - * this more efficiently than we can here, so simply let background |
---|
968 | | - * reclaim tear down all inodes. |
---|
| 659 | + * We always use background reclaim here because even if the inode is |
---|
| 660 | + * clean, it still may be under IO and hence we have wait for IO |
---|
| 661 | + * completion to occur before we can reclaim the inode. The background |
---|
| 662 | + * reclaim path handles this more efficiently than we can here, so |
---|
| 663 | + * simply let background reclaim tear down all inodes. |
---|
969 | 664 | */ |
---|
970 | 665 | xfs_inode_set_reclaim_tag(ip); |
---|
971 | 666 | } |
---|
.. | .. |
---|
1044 | 739 | return 0; |
---|
1045 | 740 | } |
---|
1046 | 741 | |
---|
1047 | | - return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); |
---|
| 742 | + return generic_drop_inode(inode); |
---|
1048 | 743 | } |
---|
1049 | 744 | |
---|
1050 | | -STATIC void |
---|
1051 | | -xfs_free_fsname( |
---|
| 745 | +static void |
---|
| 746 | +xfs_mount_free( |
---|
1052 | 747 | struct xfs_mount *mp) |
---|
1053 | 748 | { |
---|
1054 | | - kfree(mp->m_fsname); |
---|
1055 | 749 | kfree(mp->m_rtname); |
---|
1056 | 750 | kfree(mp->m_logname); |
---|
| 751 | + kmem_free(mp); |
---|
1057 | 752 | } |
---|
1058 | 753 | |
---|
1059 | 754 | STATIC int |
---|
.. | .. |
---|
1062 | 757 | int wait) |
---|
1063 | 758 | { |
---|
1064 | 759 | struct xfs_mount *mp = XFS_M(sb); |
---|
| 760 | + int error; |
---|
1065 | 761 | |
---|
1066 | 762 | /* |
---|
1067 | 763 | * Doing anything during the async pass would be counterproductive. |
---|
.. | .. |
---|
1069 | 765 | if (!wait) |
---|
1070 | 766 | return 0; |
---|
1071 | 767 | |
---|
1072 | | - xfs_log_force(mp, XFS_LOG_SYNC); |
---|
| 768 | + error = xfs_log_force(mp, XFS_LOG_SYNC); |
---|
| 769 | + if (error) |
---|
| 770 | + return error; |
---|
| 771 | + |
---|
1073 | 772 | if (laptop_mode) { |
---|
1074 | 773 | /* |
---|
1075 | 774 | * The disk must be active because we're syncing. |
---|
.. | .. |
---|
1097 | 796 | xfs_extlen_t lsize; |
---|
1098 | 797 | int64_t ffree; |
---|
1099 | 798 | |
---|
1100 | | - statp->f_type = XFS_SB_MAGIC; |
---|
| 799 | + statp->f_type = XFS_SUPER_MAGIC; |
---|
1101 | 800 | statp->f_namelen = MAXNAMELEN - 1; |
---|
1102 | 801 | |
---|
1103 | 802 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); |
---|
1104 | | - statp->f_fsid.val[0] = (u32)id; |
---|
1105 | | - statp->f_fsid.val[1] = (u32)(id >> 32); |
---|
| 803 | + statp->f_fsid = u64_to_fsid(id); |
---|
1106 | 804 | |
---|
1107 | 805 | icount = percpu_counter_sum(&mp->m_icount); |
---|
1108 | 806 | ifree = percpu_counter_sum(&mp->m_ifree); |
---|
.. | .. |
---|
1114 | 812 | statp->f_blocks = sbp->sb_dblocks - lsize; |
---|
1115 | 813 | spin_unlock(&mp->m_sb_lock); |
---|
1116 | 814 | |
---|
1117 | | - statp->f_bfree = fdblocks - mp->m_alloc_set_aside; |
---|
| 815 | + /* make sure statp->f_bfree does not underflow */ |
---|
| 816 | + statp->f_bfree = max_t(int64_t, fdblocks - mp->m_alloc_set_aside, 0); |
---|
1118 | 817 | statp->f_bavail = statp->f_bfree; |
---|
1119 | 818 | |
---|
1120 | | - fakeinos = statp->f_bfree << sbp->sb_inopblog; |
---|
| 819 | + fakeinos = XFS_FSB_TO_INO(mp, statp->f_bfree); |
---|
1121 | 820 | statp->f_files = min(icount + fakeinos, (uint64_t)XFS_MAXINUMBER); |
---|
1122 | | - if (mp->m_maxicount) |
---|
| 821 | + if (M_IGEO(mp)->maxicount) |
---|
1123 | 822 | statp->f_files = min_t(typeof(statp->f_files), |
---|
1124 | 823 | statp->f_files, |
---|
1125 | | - mp->m_maxicount); |
---|
| 824 | + M_IGEO(mp)->maxicount); |
---|
1126 | 825 | |
---|
1127 | 826 | /* If sb_icount overshot maxicount, report actual allocation */ |
---|
1128 | 827 | statp->f_files = max_t(typeof(statp->f_files), |
---|
.. | .. |
---|
1180 | 879 | * there is no log replay required to write the inodes to disk - this is the |
---|
1181 | 880 | * primary difference between a sync and a quiesce. |
---|
1182 | 881 | * |
---|
1183 | | - * Note: xfs_log_quiesce() stops background log work - the callers must ensure |
---|
1184 | | - * it is started again when appropriate. |
---|
| 882 | + * We cancel log work early here to ensure all transactions the log worker may |
---|
| 883 | + * run have finished before we clean up and log the superblock and write an |
---|
| 884 | + * unmount record. The unfreeze process is responsible for restarting the log |
---|
| 885 | + * worker correctly. |
---|
1185 | 886 | */ |
---|
1186 | 887 | void |
---|
1187 | 888 | xfs_quiesce_attr( |
---|
.. | .. |
---|
1189 | 890 | { |
---|
1190 | 891 | int error = 0; |
---|
1191 | 892 | |
---|
1192 | | - /* wait for all modifications to complete */ |
---|
1193 | | - while (atomic_read(&mp->m_active_trans) > 0) |
---|
1194 | | - delay(100); |
---|
| 893 | + cancel_delayed_work_sync(&mp->m_log->l_work); |
---|
1195 | 894 | |
---|
1196 | 895 | /* force the log to unpin objects from the now complete transactions */ |
---|
1197 | 896 | xfs_log_force(mp, XFS_LOG_SYNC); |
---|
1198 | 897 | |
---|
1199 | | - /* reclaim inodes to do any IO before the freeze completes */ |
---|
1200 | | - xfs_reclaim_inodes(mp, 0); |
---|
1201 | | - xfs_reclaim_inodes(mp, SYNC_WAIT); |
---|
1202 | 898 | |
---|
1203 | 899 | /* Push the superblock and write an unmount record */ |
---|
1204 | 900 | error = xfs_log_sbcount(mp); |
---|
1205 | 901 | if (error) |
---|
1206 | 902 | xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " |
---|
1207 | 903 | "Frozen image may not be consistent."); |
---|
1208 | | - /* |
---|
1209 | | - * Just warn here till VFS can correctly support |
---|
1210 | | - * read-only remount without racing. |
---|
1211 | | - */ |
---|
1212 | | - WARN_ON(atomic_read(&mp->m_active_trans) != 0); |
---|
1213 | | - |
---|
1214 | 904 | xfs_log_quiesce(mp); |
---|
1215 | | -} |
---|
1216 | | - |
---|
1217 | | -STATIC int |
---|
1218 | | -xfs_test_remount_options( |
---|
1219 | | - struct super_block *sb, |
---|
1220 | | - char *options) |
---|
1221 | | -{ |
---|
1222 | | - int error = 0; |
---|
1223 | | - struct xfs_mount *tmp_mp; |
---|
1224 | | - |
---|
1225 | | - tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL); |
---|
1226 | | - if (!tmp_mp) |
---|
1227 | | - return -ENOMEM; |
---|
1228 | | - |
---|
1229 | | - tmp_mp->m_super = sb; |
---|
1230 | | - error = xfs_parseargs(tmp_mp, options); |
---|
1231 | | - xfs_free_fsname(tmp_mp); |
---|
1232 | | - kmem_free(tmp_mp); |
---|
1233 | | - |
---|
1234 | | - return error; |
---|
1235 | | -} |
---|
1236 | | - |
---|
1237 | | -STATIC int |
---|
1238 | | -xfs_fs_remount( |
---|
1239 | | - struct super_block *sb, |
---|
1240 | | - int *flags, |
---|
1241 | | - char *options) |
---|
1242 | | -{ |
---|
1243 | | - struct xfs_mount *mp = XFS_M(sb); |
---|
1244 | | - xfs_sb_t *sbp = &mp->m_sb; |
---|
1245 | | - substring_t args[MAX_OPT_ARGS]; |
---|
1246 | | - char *p; |
---|
1247 | | - int error; |
---|
1248 | | - |
---|
1249 | | - /* First, check for complete junk; i.e. invalid options */ |
---|
1250 | | - error = xfs_test_remount_options(sb, options); |
---|
1251 | | - if (error) |
---|
1252 | | - return error; |
---|
1253 | | - |
---|
1254 | | - sync_filesystem(sb); |
---|
1255 | | - while ((p = strsep(&options, ",")) != NULL) { |
---|
1256 | | - int token; |
---|
1257 | | - |
---|
1258 | | - if (!*p) |
---|
1259 | | - continue; |
---|
1260 | | - |
---|
1261 | | - token = match_token(p, tokens, args); |
---|
1262 | | - switch (token) { |
---|
1263 | | - case Opt_inode64: |
---|
1264 | | - mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
---|
1265 | | - mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); |
---|
1266 | | - break; |
---|
1267 | | - case Opt_inode32: |
---|
1268 | | - mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
---|
1269 | | - mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); |
---|
1270 | | - break; |
---|
1271 | | - default: |
---|
1272 | | - /* |
---|
1273 | | - * Logically we would return an error here to prevent |
---|
1274 | | - * users from believing they might have changed |
---|
1275 | | - * mount options using remount which can't be changed. |
---|
1276 | | - * |
---|
1277 | | - * But unfortunately mount(8) adds all options from |
---|
1278 | | - * mtab and fstab to the mount arguments in some cases |
---|
1279 | | - * so we can't blindly reject options, but have to |
---|
1280 | | - * check for each specified option if it actually |
---|
1281 | | - * differs from the currently set option and only |
---|
1282 | | - * reject it if that's the case. |
---|
1283 | | - * |
---|
1284 | | - * Until that is implemented we return success for |
---|
1285 | | - * every remount request, and silently ignore all |
---|
1286 | | - * options that we can't actually change. |
---|
1287 | | - */ |
---|
1288 | | -#if 0 |
---|
1289 | | - xfs_info(mp, |
---|
1290 | | - "mount option \"%s\" not supported for remount", p); |
---|
1291 | | - return -EINVAL; |
---|
1292 | | -#else |
---|
1293 | | - break; |
---|
1294 | | -#endif |
---|
1295 | | - } |
---|
1296 | | - } |
---|
1297 | | - |
---|
1298 | | - /* ro -> rw */ |
---|
1299 | | - if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) { |
---|
1300 | | - if (mp->m_flags & XFS_MOUNT_NORECOVERY) { |
---|
1301 | | - xfs_warn(mp, |
---|
1302 | | - "ro->rw transition prohibited on norecovery mount"); |
---|
1303 | | - return -EINVAL; |
---|
1304 | | - } |
---|
1305 | | - |
---|
1306 | | - if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && |
---|
1307 | | - xfs_sb_has_ro_compat_feature(sbp, |
---|
1308 | | - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { |
---|
1309 | | - xfs_warn(mp, |
---|
1310 | | -"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem", |
---|
1311 | | - (sbp->sb_features_ro_compat & |
---|
1312 | | - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); |
---|
1313 | | - return -EINVAL; |
---|
1314 | | - } |
---|
1315 | | - |
---|
1316 | | - mp->m_flags &= ~XFS_MOUNT_RDONLY; |
---|
1317 | | - |
---|
1318 | | - /* |
---|
1319 | | - * If this is the first remount to writeable state we |
---|
1320 | | - * might have some superblock changes to update. |
---|
1321 | | - */ |
---|
1322 | | - if (mp->m_update_sb) { |
---|
1323 | | - error = xfs_sync_sb(mp, false); |
---|
1324 | | - if (error) { |
---|
1325 | | - xfs_warn(mp, "failed to write sb changes"); |
---|
1326 | | - return error; |
---|
1327 | | - } |
---|
1328 | | - mp->m_update_sb = false; |
---|
1329 | | - } |
---|
1330 | | - |
---|
1331 | | - /* |
---|
1332 | | - * Fill out the reserve pool if it is empty. Use the stashed |
---|
1333 | | - * value if it is non-zero, otherwise go with the default. |
---|
1334 | | - */ |
---|
1335 | | - xfs_restore_resvblks(mp); |
---|
1336 | | - xfs_log_work_queue(mp); |
---|
1337 | | - |
---|
1338 | | - /* Recover any CoW blocks that never got remapped. */ |
---|
1339 | | - error = xfs_reflink_recover_cow(mp); |
---|
1340 | | - if (error) { |
---|
1341 | | - xfs_err(mp, |
---|
1342 | | - "Error %d recovering leftover CoW allocations.", error); |
---|
1343 | | - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
1344 | | - return error; |
---|
1345 | | - } |
---|
1346 | | - xfs_icache_enable_reclaim(mp); |
---|
1347 | | - |
---|
1348 | | - /* Create the per-AG metadata reservation pool .*/ |
---|
1349 | | - error = xfs_fs_reserve_ag_blocks(mp); |
---|
1350 | | - if (error && error != -ENOSPC) |
---|
1351 | | - return error; |
---|
1352 | | - } |
---|
1353 | | - |
---|
1354 | | - /* rw -> ro */ |
---|
1355 | | - if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) { |
---|
1356 | | - /* |
---|
1357 | | - * Cancel background eofb scanning so it cannot race with the |
---|
1358 | | - * final log force+buftarg wait and deadlock the remount. |
---|
1359 | | - */ |
---|
1360 | | - xfs_icache_disable_reclaim(mp); |
---|
1361 | | - |
---|
1362 | | - /* Get rid of any leftover CoW reservations... */ |
---|
1363 | | - error = xfs_icache_free_cowblocks(mp, NULL); |
---|
1364 | | - if (error) { |
---|
1365 | | - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
1366 | | - return error; |
---|
1367 | | - } |
---|
1368 | | - |
---|
1369 | | - /* Free the per-AG metadata reservation pool. */ |
---|
1370 | | - error = xfs_fs_unreserve_ag_blocks(mp); |
---|
1371 | | - if (error) { |
---|
1372 | | - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
1373 | | - return error; |
---|
1374 | | - } |
---|
1375 | | - |
---|
1376 | | - /* |
---|
1377 | | - * Before we sync the metadata, we need to free up the reserve |
---|
1378 | | - * block pool so that the used block count in the superblock on |
---|
1379 | | - * disk is correct at the end of the remount. Stash the current |
---|
1380 | | - * reserve pool size so that if we get remounted rw, we can |
---|
1381 | | - * return it to the same size. |
---|
1382 | | - */ |
---|
1383 | | - xfs_save_resvblks(mp); |
---|
1384 | | - |
---|
1385 | | - xfs_quiesce_attr(mp); |
---|
1386 | | - mp->m_flags |= XFS_MOUNT_RDONLY; |
---|
1387 | | - } |
---|
1388 | | - |
---|
1389 | | - return 0; |
---|
1390 | 905 | } |
---|
1391 | 906 | |
---|
1392 | 907 | /* |
---|
.. | .. |
---|
1400 | 915 | struct super_block *sb) |
---|
1401 | 916 | { |
---|
1402 | 917 | struct xfs_mount *mp = XFS_M(sb); |
---|
| 918 | + unsigned int flags; |
---|
| 919 | + int ret; |
---|
1403 | 920 | |
---|
1404 | | - xfs_icache_disable_reclaim(mp); |
---|
| 921 | + /* |
---|
| 922 | + * The filesystem is now frozen far enough that memory reclaim |
---|
| 923 | + * cannot safely operate on the filesystem. Hence we need to |
---|
| 924 | + * set a GFP_NOFS context here to avoid recursion deadlocks. |
---|
| 925 | + */ |
---|
| 926 | + flags = memalloc_nofs_save(); |
---|
| 927 | + xfs_stop_block_reaping(mp); |
---|
1405 | 928 | xfs_save_resvblks(mp); |
---|
1406 | 929 | xfs_quiesce_attr(mp); |
---|
1407 | | - return xfs_sync_sb(mp, true); |
---|
| 930 | + ret = xfs_sync_sb(mp, true); |
---|
| 931 | + memalloc_nofs_restore(flags); |
---|
| 932 | + return ret; |
---|
1408 | 933 | } |
---|
1409 | 934 | |
---|
1410 | 935 | STATIC int |
---|
.. | .. |
---|
1415 | 940 | |
---|
1416 | 941 | xfs_restore_resvblks(mp); |
---|
1417 | 942 | xfs_log_work_queue(mp); |
---|
1418 | | - xfs_icache_enable_reclaim(mp); |
---|
| 943 | + xfs_start_block_reaping(mp); |
---|
1419 | 944 | return 0; |
---|
1420 | | -} |
---|
1421 | | - |
---|
1422 | | -STATIC int |
---|
1423 | | -xfs_fs_show_options( |
---|
1424 | | - struct seq_file *m, |
---|
1425 | | - struct dentry *root) |
---|
1426 | | -{ |
---|
1427 | | - return xfs_showargs(XFS_M(root->d_sb), m); |
---|
1428 | 945 | } |
---|
1429 | 946 | |
---|
1430 | 947 | /* |
---|
.. | .. |
---|
1513 | 1030 | if (error) |
---|
1514 | 1031 | goto free_ifree; |
---|
1515 | 1032 | |
---|
| 1033 | + error = percpu_counter_init(&mp->m_delalloc_blks, 0, GFP_KERNEL); |
---|
| 1034 | + if (error) |
---|
| 1035 | + goto free_fdblocks; |
---|
| 1036 | + |
---|
1516 | 1037 | return 0; |
---|
1517 | 1038 | |
---|
| 1039 | +free_fdblocks: |
---|
| 1040 | + percpu_counter_destroy(&mp->m_fdblocks); |
---|
1518 | 1041 | free_ifree: |
---|
1519 | 1042 | percpu_counter_destroy(&mp->m_ifree); |
---|
1520 | 1043 | free_icount: |
---|
.. | .. |
---|
1538 | 1061 | percpu_counter_destroy(&mp->m_icount); |
---|
1539 | 1062 | percpu_counter_destroy(&mp->m_ifree); |
---|
1540 | 1063 | percpu_counter_destroy(&mp->m_fdblocks); |
---|
| 1064 | + ASSERT(XFS_FORCED_SHUTDOWN(mp) || |
---|
| 1065 | + percpu_counter_sum(&mp->m_delalloc_blks) == 0); |
---|
| 1066 | + percpu_counter_destroy(&mp->m_delalloc_blks); |
---|
1541 | 1067 | } |
---|
1542 | 1068 | |
---|
1543 | | -static struct xfs_mount * |
---|
1544 | | -xfs_mount_alloc( |
---|
1545 | | - struct super_block *sb) |
---|
1546 | | -{ |
---|
1547 | | - struct xfs_mount *mp; |
---|
1548 | | - |
---|
1549 | | - mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
---|
1550 | | - if (!mp) |
---|
1551 | | - return NULL; |
---|
1552 | | - |
---|
1553 | | - mp->m_super = sb; |
---|
1554 | | - spin_lock_init(&mp->m_sb_lock); |
---|
1555 | | - spin_lock_init(&mp->m_agirotor_lock); |
---|
1556 | | - INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); |
---|
1557 | | - spin_lock_init(&mp->m_perag_lock); |
---|
1558 | | - mutex_init(&mp->m_growlock); |
---|
1559 | | - atomic_set(&mp->m_active_trans, 0); |
---|
1560 | | - INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); |
---|
1561 | | - INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); |
---|
1562 | | - INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker); |
---|
1563 | | - mp->m_kobj.kobject.kset = xfs_kset; |
---|
1564 | | - /* |
---|
1565 | | - * We don't create the finobt per-ag space reservation until after log |
---|
1566 | | - * recovery, so we must set this to true so that an ifree transaction |
---|
1567 | | - * started during log recovery will not depend on space reservations |
---|
1568 | | - * for finobt expansion. |
---|
1569 | | - */ |
---|
1570 | | - mp->m_finobt_nores = true; |
---|
1571 | | - return mp; |
---|
1572 | | -} |
---|
1573 | | - |
---|
1574 | | - |
---|
1575 | | -STATIC int |
---|
1576 | | -xfs_fs_fill_super( |
---|
1577 | | - struct super_block *sb, |
---|
1578 | | - void *data, |
---|
1579 | | - int silent) |
---|
1580 | | -{ |
---|
1581 | | - struct inode *root; |
---|
1582 | | - struct xfs_mount *mp = NULL; |
---|
1583 | | - int flags = 0, error = -ENOMEM; |
---|
1584 | | - |
---|
1585 | | - /* |
---|
1586 | | - * allocate mp and do all low-level struct initializations before we |
---|
1587 | | - * attach it to the super |
---|
1588 | | - */ |
---|
1589 | | - mp = xfs_mount_alloc(sb); |
---|
1590 | | - if (!mp) |
---|
1591 | | - goto out; |
---|
1592 | | - sb->s_fs_info = mp; |
---|
1593 | | - |
---|
1594 | | - error = xfs_parseargs(mp, (char *)data); |
---|
1595 | | - if (error) |
---|
1596 | | - goto out_free_fsname; |
---|
1597 | | - |
---|
1598 | | - sb_min_blocksize(sb, BBSIZE); |
---|
1599 | | - sb->s_xattr = xfs_xattr_handlers; |
---|
1600 | | - sb->s_export_op = &xfs_export_operations; |
---|
1601 | | -#ifdef CONFIG_XFS_QUOTA |
---|
1602 | | - sb->s_qcop = &xfs_quotactl_operations; |
---|
1603 | | - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; |
---|
1604 | | -#endif |
---|
1605 | | - sb->s_op = &xfs_super_operations; |
---|
1606 | | - |
---|
1607 | | - /* |
---|
1608 | | - * Delay mount work if the debug hook is set. This is debug |
---|
1609 | | - * instrumention to coordinate simulation of xfs mount failures with |
---|
1610 | | - * VFS superblock operations |
---|
1611 | | - */ |
---|
1612 | | - if (xfs_globals.mount_delay) { |
---|
1613 | | - xfs_notice(mp, "Delaying mount for %d seconds.", |
---|
1614 | | - xfs_globals.mount_delay); |
---|
1615 | | - msleep(xfs_globals.mount_delay * 1000); |
---|
1616 | | - } |
---|
1617 | | - |
---|
1618 | | - if (silent) |
---|
1619 | | - flags |= XFS_MFSI_QUIET; |
---|
1620 | | - |
---|
1621 | | - error = xfs_open_devices(mp); |
---|
1622 | | - if (error) |
---|
1623 | | - goto out_free_fsname; |
---|
1624 | | - |
---|
1625 | | - error = xfs_init_mount_workqueues(mp); |
---|
1626 | | - if (error) |
---|
1627 | | - goto out_close_devices; |
---|
1628 | | - |
---|
1629 | | - error = xfs_init_percpu_counters(mp); |
---|
1630 | | - if (error) |
---|
1631 | | - goto out_destroy_workqueues; |
---|
1632 | | - |
---|
1633 | | - /* Allocate stats memory before we do operations that might use it */ |
---|
1634 | | - mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); |
---|
1635 | | - if (!mp->m_stats.xs_stats) { |
---|
1636 | | - error = -ENOMEM; |
---|
1637 | | - goto out_destroy_counters; |
---|
1638 | | - } |
---|
1639 | | - |
---|
1640 | | - error = xfs_readsb(mp, flags); |
---|
1641 | | - if (error) |
---|
1642 | | - goto out_free_stats; |
---|
1643 | | - |
---|
1644 | | - error = xfs_finish_flags(mp); |
---|
1645 | | - if (error) |
---|
1646 | | - goto out_free_sb; |
---|
1647 | | - |
---|
1648 | | - error = xfs_setup_devices(mp); |
---|
1649 | | - if (error) |
---|
1650 | | - goto out_free_sb; |
---|
1651 | | - |
---|
1652 | | - error = xfs_filestream_mount(mp); |
---|
1653 | | - if (error) |
---|
1654 | | - goto out_free_sb; |
---|
1655 | | - |
---|
1656 | | - /* |
---|
1657 | | - * we must configure the block size in the superblock before we run the |
---|
1658 | | - * full mount process as the mount process can lookup and cache inodes. |
---|
1659 | | - */ |
---|
1660 | | - sb->s_magic = XFS_SB_MAGIC; |
---|
1661 | | - sb->s_blocksize = mp->m_sb.sb_blocksize; |
---|
1662 | | - sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
---|
1663 | | - sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); |
---|
1664 | | - sb->s_max_links = XFS_MAXLINK; |
---|
1665 | | - sb->s_time_gran = 1; |
---|
1666 | | - set_posix_acl_flag(sb); |
---|
1667 | | - |
---|
1668 | | - /* version 5 superblocks support inode version counters. */ |
---|
1669 | | - if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) |
---|
1670 | | - sb->s_flags |= SB_I_VERSION; |
---|
1671 | | - |
---|
1672 | | - if (mp->m_flags & XFS_MOUNT_DAX) { |
---|
1673 | | - bool rtdev_is_dax = false, datadev_is_dax; |
---|
1674 | | - |
---|
1675 | | - xfs_warn(mp, |
---|
1676 | | - "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); |
---|
1677 | | - |
---|
1678 | | - datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev, |
---|
1679 | | - sb->s_blocksize); |
---|
1680 | | - if (mp->m_rtdev_targp) |
---|
1681 | | - rtdev_is_dax = bdev_dax_supported( |
---|
1682 | | - mp->m_rtdev_targp->bt_bdev, sb->s_blocksize); |
---|
1683 | | - if (!rtdev_is_dax && !datadev_is_dax) { |
---|
1684 | | - xfs_alert(mp, |
---|
1685 | | - "DAX unsupported by block device. Turning off DAX."); |
---|
1686 | | - mp->m_flags &= ~XFS_MOUNT_DAX; |
---|
1687 | | - } |
---|
1688 | | - if (xfs_sb_version_hasreflink(&mp->m_sb)) { |
---|
1689 | | - xfs_alert(mp, |
---|
1690 | | - "DAX and reflink cannot be used together!"); |
---|
1691 | | - error = -EINVAL; |
---|
1692 | | - goto out_filestream_unmount; |
---|
1693 | | - } |
---|
1694 | | - } |
---|
1695 | | - |
---|
1696 | | - if (mp->m_flags & XFS_MOUNT_DISCARD) { |
---|
1697 | | - struct request_queue *q = bdev_get_queue(sb->s_bdev); |
---|
1698 | | - |
---|
1699 | | - if (!blk_queue_discard(q)) { |
---|
1700 | | - xfs_warn(mp, "mounting with \"discard\" option, but " |
---|
1701 | | - "the device does not support discard"); |
---|
1702 | | - mp->m_flags &= ~XFS_MOUNT_DISCARD; |
---|
1703 | | - } |
---|
1704 | | - } |
---|
1705 | | - |
---|
1706 | | - if (xfs_sb_version_hasreflink(&mp->m_sb) && mp->m_sb.sb_rblocks) { |
---|
1707 | | - xfs_alert(mp, |
---|
1708 | | - "reflink not compatible with realtime device!"); |
---|
1709 | | - error = -EINVAL; |
---|
1710 | | - goto out_filestream_unmount; |
---|
1711 | | - } |
---|
1712 | | - |
---|
1713 | | - if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks) { |
---|
1714 | | - xfs_alert(mp, |
---|
1715 | | - "reverse mapping btree not compatible with realtime device!"); |
---|
1716 | | - error = -EINVAL; |
---|
1717 | | - goto out_filestream_unmount; |
---|
1718 | | - } |
---|
1719 | | - |
---|
1720 | | - error = xfs_mountfs(mp); |
---|
1721 | | - if (error) |
---|
1722 | | - goto out_filestream_unmount; |
---|
1723 | | - |
---|
1724 | | - root = igrab(VFS_I(mp->m_rootip)); |
---|
1725 | | - if (!root) { |
---|
1726 | | - error = -ENOENT; |
---|
1727 | | - goto out_unmount; |
---|
1728 | | - } |
---|
1729 | | - sb->s_root = d_make_root(root); |
---|
1730 | | - if (!sb->s_root) { |
---|
1731 | | - error = -ENOMEM; |
---|
1732 | | - goto out_unmount; |
---|
1733 | | - } |
---|
1734 | | - |
---|
1735 | | - return 0; |
---|
1736 | | - |
---|
1737 | | - out_filestream_unmount: |
---|
1738 | | - xfs_filestream_unmount(mp); |
---|
1739 | | - out_free_sb: |
---|
1740 | | - xfs_freesb(mp); |
---|
1741 | | - out_free_stats: |
---|
1742 | | - free_percpu(mp->m_stats.xs_stats); |
---|
1743 | | - out_destroy_counters: |
---|
1744 | | - xfs_destroy_percpu_counters(mp); |
---|
1745 | | - out_destroy_workqueues: |
---|
1746 | | - xfs_destroy_mount_workqueues(mp); |
---|
1747 | | - out_close_devices: |
---|
1748 | | - xfs_close_devices(mp); |
---|
1749 | | - out_free_fsname: |
---|
1750 | | - sb->s_fs_info = NULL; |
---|
1751 | | - xfs_free_fsname(mp); |
---|
1752 | | - kfree(mp); |
---|
1753 | | - out: |
---|
1754 | | - return error; |
---|
1755 | | - |
---|
1756 | | - out_unmount: |
---|
1757 | | - xfs_filestream_unmount(mp); |
---|
1758 | | - xfs_unmountfs(mp); |
---|
1759 | | - goto out_free_sb; |
---|
1760 | | -} |
---|
1761 | | - |
---|
1762 | | -STATIC void |
---|
| 1069 | +static void |
---|
1763 | 1070 | xfs_fs_put_super( |
---|
1764 | 1071 | struct super_block *sb) |
---|
1765 | 1072 | { |
---|
.. | .. |
---|
1780 | 1087 | xfs_close_devices(mp); |
---|
1781 | 1088 | |
---|
1782 | 1089 | sb->s_fs_info = NULL; |
---|
1783 | | - xfs_free_fsname(mp); |
---|
1784 | | - kfree(mp); |
---|
1785 | | -} |
---|
1786 | | - |
---|
1787 | | -STATIC struct dentry * |
---|
1788 | | -xfs_fs_mount( |
---|
1789 | | - struct file_system_type *fs_type, |
---|
1790 | | - int flags, |
---|
1791 | | - const char *dev_name, |
---|
1792 | | - void *data) |
---|
1793 | | -{ |
---|
1794 | | - return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); |
---|
| 1090 | + xfs_mount_free(mp); |
---|
1795 | 1091 | } |
---|
1796 | 1092 | |
---|
1797 | 1093 | static long |
---|
.. | .. |
---|
1823 | 1119 | .freeze_fs = xfs_fs_freeze, |
---|
1824 | 1120 | .unfreeze_fs = xfs_fs_unfreeze, |
---|
1825 | 1121 | .statfs = xfs_fs_statfs, |
---|
1826 | | - .remount_fs = xfs_fs_remount, |
---|
1827 | 1122 | .show_options = xfs_fs_show_options, |
---|
1828 | 1123 | .nr_cached_objects = xfs_fs_nr_cached_objects, |
---|
1829 | 1124 | .free_cached_objects = xfs_fs_free_cached_objects, |
---|
1830 | 1125 | }; |
---|
1831 | 1126 | |
---|
| 1127 | +static int |
---|
| 1128 | +suffix_kstrtoint( |
---|
| 1129 | + const char *s, |
---|
| 1130 | + unsigned int base, |
---|
| 1131 | + int *res) |
---|
| 1132 | +{ |
---|
| 1133 | + int last, shift_left_factor = 0, _res; |
---|
| 1134 | + char *value; |
---|
| 1135 | + int ret = 0; |
---|
| 1136 | + |
---|
| 1137 | + value = kstrdup(s, GFP_KERNEL); |
---|
| 1138 | + if (!value) |
---|
| 1139 | + return -ENOMEM; |
---|
| 1140 | + |
---|
| 1141 | + last = strlen(value) - 1; |
---|
| 1142 | + if (value[last] == 'K' || value[last] == 'k') { |
---|
| 1143 | + shift_left_factor = 10; |
---|
| 1144 | + value[last] = '\0'; |
---|
| 1145 | + } |
---|
| 1146 | + if (value[last] == 'M' || value[last] == 'm') { |
---|
| 1147 | + shift_left_factor = 20; |
---|
| 1148 | + value[last] = '\0'; |
---|
| 1149 | + } |
---|
| 1150 | + if (value[last] == 'G' || value[last] == 'g') { |
---|
| 1151 | + shift_left_factor = 30; |
---|
| 1152 | + value[last] = '\0'; |
---|
| 1153 | + } |
---|
| 1154 | + |
---|
| 1155 | + if (kstrtoint(value, base, &_res)) |
---|
| 1156 | + ret = -EINVAL; |
---|
| 1157 | + kfree(value); |
---|
| 1158 | + *res = _res << shift_left_factor; |
---|
| 1159 | + return ret; |
---|
| 1160 | +} |
---|
| 1161 | + |
---|
| 1162 | +static inline void |
---|
| 1163 | +xfs_fs_warn_deprecated( |
---|
| 1164 | + struct fs_context *fc, |
---|
| 1165 | + struct fs_parameter *param, |
---|
| 1166 | + uint64_t flag, |
---|
| 1167 | + bool value) |
---|
| 1168 | +{ |
---|
| 1169 | + /* Don't print the warning if reconfiguring and current mount point |
---|
| 1170 | + * already had the flag set |
---|
| 1171 | + */ |
---|
| 1172 | + if ((fc->purpose & FS_CONTEXT_FOR_RECONFIGURE) && |
---|
| 1173 | + !!(XFS_M(fc->root->d_sb)->m_flags & flag) == value) |
---|
| 1174 | + return; |
---|
| 1175 | + xfs_warn(fc->s_fs_info, "%s mount option is deprecated.", param->key); |
---|
| 1176 | +} |
---|
| 1177 | + |
---|
| 1178 | +/* |
---|
| 1179 | + * Set mount state from a mount option. |
---|
| 1180 | + * |
---|
| 1181 | + * NOTE: mp->m_super is NULL here! |
---|
| 1182 | + */ |
---|
| 1183 | +static int |
---|
| 1184 | +xfs_fc_parse_param( |
---|
| 1185 | + struct fs_context *fc, |
---|
| 1186 | + struct fs_parameter *param) |
---|
| 1187 | +{ |
---|
| 1188 | + struct xfs_mount *parsing_mp = fc->s_fs_info; |
---|
| 1189 | + struct fs_parse_result result; |
---|
| 1190 | + int size = 0; |
---|
| 1191 | + int opt; |
---|
| 1192 | + |
---|
| 1193 | + opt = fs_parse(fc, xfs_fs_parameters, param, &result); |
---|
| 1194 | + if (opt < 0) |
---|
| 1195 | + return opt; |
---|
| 1196 | + |
---|
| 1197 | + switch (opt) { |
---|
| 1198 | + case Opt_logbufs: |
---|
| 1199 | + parsing_mp->m_logbufs = result.uint_32; |
---|
| 1200 | + return 0; |
---|
| 1201 | + case Opt_logbsize: |
---|
| 1202 | + if (suffix_kstrtoint(param->string, 10, &parsing_mp->m_logbsize)) |
---|
| 1203 | + return -EINVAL; |
---|
| 1204 | + return 0; |
---|
| 1205 | + case Opt_logdev: |
---|
| 1206 | + kfree(parsing_mp->m_logname); |
---|
| 1207 | + parsing_mp->m_logname = kstrdup(param->string, GFP_KERNEL); |
---|
| 1208 | + if (!parsing_mp->m_logname) |
---|
| 1209 | + return -ENOMEM; |
---|
| 1210 | + return 0; |
---|
| 1211 | + case Opt_rtdev: |
---|
| 1212 | + kfree(parsing_mp->m_rtname); |
---|
| 1213 | + parsing_mp->m_rtname = kstrdup(param->string, GFP_KERNEL); |
---|
| 1214 | + if (!parsing_mp->m_rtname) |
---|
| 1215 | + return -ENOMEM; |
---|
| 1216 | + return 0; |
---|
| 1217 | + case Opt_allocsize: |
---|
| 1218 | + if (suffix_kstrtoint(param->string, 10, &size)) |
---|
| 1219 | + return -EINVAL; |
---|
| 1220 | + parsing_mp->m_allocsize_log = ffs(size) - 1; |
---|
| 1221 | + parsing_mp->m_flags |= XFS_MOUNT_ALLOCSIZE; |
---|
| 1222 | + return 0; |
---|
| 1223 | + case Opt_grpid: |
---|
| 1224 | + case Opt_bsdgroups: |
---|
| 1225 | + parsing_mp->m_flags |= XFS_MOUNT_GRPID; |
---|
| 1226 | + return 0; |
---|
| 1227 | + case Opt_nogrpid: |
---|
| 1228 | + case Opt_sysvgroups: |
---|
| 1229 | + parsing_mp->m_flags &= ~XFS_MOUNT_GRPID; |
---|
| 1230 | + return 0; |
---|
| 1231 | + case Opt_wsync: |
---|
| 1232 | + parsing_mp->m_flags |= XFS_MOUNT_WSYNC; |
---|
| 1233 | + return 0; |
---|
| 1234 | + case Opt_norecovery: |
---|
| 1235 | + parsing_mp->m_flags |= XFS_MOUNT_NORECOVERY; |
---|
| 1236 | + return 0; |
---|
| 1237 | + case Opt_noalign: |
---|
| 1238 | + parsing_mp->m_flags |= XFS_MOUNT_NOALIGN; |
---|
| 1239 | + return 0; |
---|
| 1240 | + case Opt_swalloc: |
---|
| 1241 | + parsing_mp->m_flags |= XFS_MOUNT_SWALLOC; |
---|
| 1242 | + return 0; |
---|
| 1243 | + case Opt_sunit: |
---|
| 1244 | + parsing_mp->m_dalign = result.uint_32; |
---|
| 1245 | + return 0; |
---|
| 1246 | + case Opt_swidth: |
---|
| 1247 | + parsing_mp->m_swidth = result.uint_32; |
---|
| 1248 | + return 0; |
---|
| 1249 | + case Opt_inode32: |
---|
| 1250 | + parsing_mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
---|
| 1251 | + return 0; |
---|
| 1252 | + case Opt_inode64: |
---|
| 1253 | + parsing_mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
---|
| 1254 | + return 0; |
---|
| 1255 | + case Opt_nouuid: |
---|
| 1256 | + parsing_mp->m_flags |= XFS_MOUNT_NOUUID; |
---|
| 1257 | + return 0; |
---|
| 1258 | + case Opt_largeio: |
---|
| 1259 | + parsing_mp->m_flags |= XFS_MOUNT_LARGEIO; |
---|
| 1260 | + return 0; |
---|
| 1261 | + case Opt_nolargeio: |
---|
| 1262 | + parsing_mp->m_flags &= ~XFS_MOUNT_LARGEIO; |
---|
| 1263 | + return 0; |
---|
| 1264 | + case Opt_filestreams: |
---|
| 1265 | + parsing_mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
---|
| 1266 | + return 0; |
---|
| 1267 | + case Opt_noquota: |
---|
| 1268 | + parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; |
---|
| 1269 | + parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; |
---|
| 1270 | + parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; |
---|
| 1271 | + return 0; |
---|
| 1272 | + case Opt_quota: |
---|
| 1273 | + case Opt_uquota: |
---|
| 1274 | + case Opt_usrquota: |
---|
| 1275 | + parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
---|
| 1276 | + XFS_UQUOTA_ENFD); |
---|
| 1277 | + return 0; |
---|
| 1278 | + case Opt_qnoenforce: |
---|
| 1279 | + case Opt_uqnoenforce: |
---|
| 1280 | + parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
---|
| 1281 | + parsing_mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
---|
| 1282 | + return 0; |
---|
| 1283 | + case Opt_pquota: |
---|
| 1284 | + case Opt_prjquota: |
---|
| 1285 | + parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
---|
| 1286 | + XFS_PQUOTA_ENFD); |
---|
| 1287 | + return 0; |
---|
| 1288 | + case Opt_pqnoenforce: |
---|
| 1289 | + parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
---|
| 1290 | + parsing_mp->m_qflags &= ~XFS_PQUOTA_ENFD; |
---|
| 1291 | + return 0; |
---|
| 1292 | + case Opt_gquota: |
---|
| 1293 | + case Opt_grpquota: |
---|
| 1294 | + parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
---|
| 1295 | + XFS_GQUOTA_ENFD); |
---|
| 1296 | + return 0; |
---|
| 1297 | + case Opt_gqnoenforce: |
---|
| 1298 | + parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
---|
| 1299 | + parsing_mp->m_qflags &= ~XFS_GQUOTA_ENFD; |
---|
| 1300 | + return 0; |
---|
| 1301 | + case Opt_discard: |
---|
| 1302 | + parsing_mp->m_flags |= XFS_MOUNT_DISCARD; |
---|
| 1303 | + return 0; |
---|
| 1304 | + case Opt_nodiscard: |
---|
| 1305 | + parsing_mp->m_flags &= ~XFS_MOUNT_DISCARD; |
---|
| 1306 | + return 0; |
---|
| 1307 | +#ifdef CONFIG_FS_DAX |
---|
| 1308 | + case Opt_dax: |
---|
| 1309 | + xfs_mount_set_dax_mode(parsing_mp, XFS_DAX_ALWAYS); |
---|
| 1310 | + return 0; |
---|
| 1311 | + case Opt_dax_enum: |
---|
| 1312 | + xfs_mount_set_dax_mode(parsing_mp, result.uint_32); |
---|
| 1313 | + return 0; |
---|
| 1314 | +#endif |
---|
| 1315 | + /* Following mount options will be removed in September 2025 */ |
---|
| 1316 | + case Opt_ikeep: |
---|
| 1317 | + xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_IKEEP, true); |
---|
| 1318 | + parsing_mp->m_flags |= XFS_MOUNT_IKEEP; |
---|
| 1319 | + return 0; |
---|
| 1320 | + case Opt_noikeep: |
---|
| 1321 | + xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_IKEEP, false); |
---|
| 1322 | + parsing_mp->m_flags &= ~XFS_MOUNT_IKEEP; |
---|
| 1323 | + return 0; |
---|
| 1324 | + case Opt_attr2: |
---|
| 1325 | + xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_ATTR2, true); |
---|
| 1326 | + parsing_mp->m_flags |= XFS_MOUNT_ATTR2; |
---|
| 1327 | + return 0; |
---|
| 1328 | + case Opt_noattr2: |
---|
| 1329 | + xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_NOATTR2, true); |
---|
| 1330 | + parsing_mp->m_flags &= ~XFS_MOUNT_ATTR2; |
---|
| 1331 | + parsing_mp->m_flags |= XFS_MOUNT_NOATTR2; |
---|
| 1332 | + return 0; |
---|
| 1333 | + default: |
---|
| 1334 | + xfs_warn(parsing_mp, "unknown mount option [%s].", param->key); |
---|
| 1335 | + return -EINVAL; |
---|
| 1336 | + } |
---|
| 1337 | + |
---|
| 1338 | + return 0; |
---|
| 1339 | +} |
---|
| 1340 | + |
---|
| 1341 | +static int |
---|
| 1342 | +xfs_fc_validate_params( |
---|
| 1343 | + struct xfs_mount *mp) |
---|
| 1344 | +{ |
---|
| 1345 | + /* |
---|
| 1346 | + * no recovery flag requires a read-only mount |
---|
| 1347 | + */ |
---|
| 1348 | + if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && |
---|
| 1349 | + !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
---|
| 1350 | + xfs_warn(mp, "no-recovery mounts must be read-only."); |
---|
| 1351 | + return -EINVAL; |
---|
| 1352 | + } |
---|
| 1353 | + |
---|
| 1354 | + if ((mp->m_flags & XFS_MOUNT_NOALIGN) && |
---|
| 1355 | + (mp->m_dalign || mp->m_swidth)) { |
---|
| 1356 | + xfs_warn(mp, |
---|
| 1357 | + "sunit and swidth options incompatible with the noalign option"); |
---|
| 1358 | + return -EINVAL; |
---|
| 1359 | + } |
---|
| 1360 | + |
---|
| 1361 | + if (!IS_ENABLED(CONFIG_XFS_QUOTA) && mp->m_qflags != 0) { |
---|
| 1362 | + xfs_warn(mp, "quota support not available in this kernel."); |
---|
| 1363 | + return -EINVAL; |
---|
| 1364 | + } |
---|
| 1365 | + |
---|
| 1366 | + if ((mp->m_dalign && !mp->m_swidth) || |
---|
| 1367 | + (!mp->m_dalign && mp->m_swidth)) { |
---|
| 1368 | + xfs_warn(mp, "sunit and swidth must be specified together"); |
---|
| 1369 | + return -EINVAL; |
---|
| 1370 | + } |
---|
| 1371 | + |
---|
| 1372 | + if (mp->m_dalign && (mp->m_swidth % mp->m_dalign != 0)) { |
---|
| 1373 | + xfs_warn(mp, |
---|
| 1374 | + "stripe width (%d) must be a multiple of the stripe unit (%d)", |
---|
| 1375 | + mp->m_swidth, mp->m_dalign); |
---|
| 1376 | + return -EINVAL; |
---|
| 1377 | + } |
---|
| 1378 | + |
---|
| 1379 | + if (mp->m_logbufs != -1 && |
---|
| 1380 | + mp->m_logbufs != 0 && |
---|
| 1381 | + (mp->m_logbufs < XLOG_MIN_ICLOGS || |
---|
| 1382 | + mp->m_logbufs > XLOG_MAX_ICLOGS)) { |
---|
| 1383 | + xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", |
---|
| 1384 | + mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); |
---|
| 1385 | + return -EINVAL; |
---|
| 1386 | + } |
---|
| 1387 | + |
---|
| 1388 | + if (mp->m_logbsize != -1 && |
---|
| 1389 | + mp->m_logbsize != 0 && |
---|
| 1390 | + (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || |
---|
| 1391 | + mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || |
---|
| 1392 | + !is_power_of_2(mp->m_logbsize))) { |
---|
| 1393 | + xfs_warn(mp, |
---|
| 1394 | + "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", |
---|
| 1395 | + mp->m_logbsize); |
---|
| 1396 | + return -EINVAL; |
---|
| 1397 | + } |
---|
| 1398 | + |
---|
| 1399 | + if ((mp->m_flags & XFS_MOUNT_ALLOCSIZE) && |
---|
| 1400 | + (mp->m_allocsize_log > XFS_MAX_IO_LOG || |
---|
| 1401 | + mp->m_allocsize_log < XFS_MIN_IO_LOG)) { |
---|
| 1402 | + xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", |
---|
| 1403 | + mp->m_allocsize_log, XFS_MIN_IO_LOG, XFS_MAX_IO_LOG); |
---|
| 1404 | + return -EINVAL; |
---|
| 1405 | + } |
---|
| 1406 | + |
---|
| 1407 | + return 0; |
---|
| 1408 | +} |
---|
| 1409 | + |
---|
| 1410 | +static int |
---|
| 1411 | +xfs_fc_fill_super( |
---|
| 1412 | + struct super_block *sb, |
---|
| 1413 | + struct fs_context *fc) |
---|
| 1414 | +{ |
---|
| 1415 | + struct xfs_mount *mp = sb->s_fs_info; |
---|
| 1416 | + struct inode *root; |
---|
| 1417 | + int flags = 0, error; |
---|
| 1418 | + |
---|
| 1419 | + mp->m_super = sb; |
---|
| 1420 | + |
---|
| 1421 | + error = xfs_fc_validate_params(mp); |
---|
| 1422 | + if (error) |
---|
| 1423 | + goto out_free_names; |
---|
| 1424 | + |
---|
| 1425 | + sb_min_blocksize(sb, BBSIZE); |
---|
| 1426 | + sb->s_xattr = xfs_xattr_handlers; |
---|
| 1427 | + sb->s_export_op = &xfs_export_operations; |
---|
| 1428 | +#ifdef CONFIG_XFS_QUOTA |
---|
| 1429 | + sb->s_qcop = &xfs_quotactl_operations; |
---|
| 1430 | + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; |
---|
| 1431 | +#endif |
---|
| 1432 | + sb->s_op = &xfs_super_operations; |
---|
| 1433 | + |
---|
| 1434 | + /* |
---|
| 1435 | + * Delay mount work if the debug hook is set. This is debug |
---|
| 1436 | + * instrumention to coordinate simulation of xfs mount failures with |
---|
| 1437 | + * VFS superblock operations |
---|
| 1438 | + */ |
---|
| 1439 | + if (xfs_globals.mount_delay) { |
---|
| 1440 | + xfs_notice(mp, "Delaying mount for %d seconds.", |
---|
| 1441 | + xfs_globals.mount_delay); |
---|
| 1442 | + msleep(xfs_globals.mount_delay * 1000); |
---|
| 1443 | + } |
---|
| 1444 | + |
---|
| 1445 | + if (fc->sb_flags & SB_SILENT) |
---|
| 1446 | + flags |= XFS_MFSI_QUIET; |
---|
| 1447 | + |
---|
| 1448 | + error = xfs_open_devices(mp); |
---|
| 1449 | + if (error) |
---|
| 1450 | + goto out_free_names; |
---|
| 1451 | + |
---|
| 1452 | + error = xfs_init_mount_workqueues(mp); |
---|
| 1453 | + if (error) |
---|
| 1454 | + goto out_close_devices; |
---|
| 1455 | + |
---|
| 1456 | + error = xfs_init_percpu_counters(mp); |
---|
| 1457 | + if (error) |
---|
| 1458 | + goto out_destroy_workqueues; |
---|
| 1459 | + |
---|
| 1460 | + /* Allocate stats memory before we do operations that might use it */ |
---|
| 1461 | + mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); |
---|
| 1462 | + if (!mp->m_stats.xs_stats) { |
---|
| 1463 | + error = -ENOMEM; |
---|
| 1464 | + goto out_destroy_counters; |
---|
| 1465 | + } |
---|
| 1466 | + |
---|
| 1467 | + error = xfs_readsb(mp, flags); |
---|
| 1468 | + if (error) |
---|
| 1469 | + goto out_free_stats; |
---|
| 1470 | + |
---|
| 1471 | + error = xfs_finish_flags(mp); |
---|
| 1472 | + if (error) |
---|
| 1473 | + goto out_free_sb; |
---|
| 1474 | + |
---|
| 1475 | + error = xfs_setup_devices(mp); |
---|
| 1476 | + if (error) |
---|
| 1477 | + goto out_free_sb; |
---|
| 1478 | + |
---|
| 1479 | + /* V4 support is undergoing deprecation. */ |
---|
| 1480 | + if (!xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
| 1481 | +#ifdef CONFIG_XFS_SUPPORT_V4 |
---|
| 1482 | + xfs_warn_once(mp, |
---|
| 1483 | + "Deprecated V4 format (crc=0) will not be supported after September 2030."); |
---|
| 1484 | +#else |
---|
| 1485 | + xfs_warn(mp, |
---|
| 1486 | + "Deprecated V4 format (crc=0) not supported by kernel."); |
---|
| 1487 | + error = -EINVAL; |
---|
| 1488 | + goto out_free_sb; |
---|
| 1489 | +#endif |
---|
| 1490 | + } |
---|
| 1491 | + |
---|
| 1492 | + /* |
---|
| 1493 | + * XFS block mappings use 54 bits to store the logical block offset. |
---|
| 1494 | + * This should suffice to handle the maximum file size that the VFS |
---|
| 1495 | + * supports (currently 2^63 bytes on 64-bit and ULONG_MAX << PAGE_SHIFT |
---|
| 1496 | + * bytes on 32-bit), but as XFS and VFS have gotten the s_maxbytes |
---|
| 1497 | + * calculation wrong on 32-bit kernels in the past, we'll add a WARN_ON |
---|
| 1498 | + * to check this assertion. |
---|
| 1499 | + * |
---|
| 1500 | + * Avoid integer overflow by comparing the maximum bmbt offset to the |
---|
| 1501 | + * maximum pagecache offset in units of fs blocks. |
---|
| 1502 | + */ |
---|
| 1503 | + if (XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE) > XFS_MAX_FILEOFF) { |
---|
| 1504 | + xfs_warn(mp, |
---|
| 1505 | +"MAX_LFS_FILESIZE block offset (%llu) exceeds extent map maximum (%llu)!", |
---|
| 1506 | + XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE), |
---|
| 1507 | + XFS_MAX_FILEOFF); |
---|
| 1508 | + error = -EINVAL; |
---|
| 1509 | + goto out_free_sb; |
---|
| 1510 | + } |
---|
| 1511 | + |
---|
| 1512 | + error = xfs_filestream_mount(mp); |
---|
| 1513 | + if (error) |
---|
| 1514 | + goto out_free_sb; |
---|
| 1515 | + |
---|
| 1516 | + /* |
---|
| 1517 | + * we must configure the block size in the superblock before we run the |
---|
| 1518 | + * full mount process as the mount process can lookup and cache inodes. |
---|
| 1519 | + */ |
---|
| 1520 | + sb->s_magic = XFS_SUPER_MAGIC; |
---|
| 1521 | + sb->s_blocksize = mp->m_sb.sb_blocksize; |
---|
| 1522 | + sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
---|
| 1523 | + sb->s_maxbytes = MAX_LFS_FILESIZE; |
---|
| 1524 | + sb->s_max_links = XFS_MAXLINK; |
---|
| 1525 | + sb->s_time_gran = 1; |
---|
| 1526 | + if (xfs_sb_version_hasbigtime(&mp->m_sb)) { |
---|
| 1527 | + sb->s_time_min = xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MIN); |
---|
| 1528 | + sb->s_time_max = xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MAX); |
---|
| 1529 | + } else { |
---|
| 1530 | + sb->s_time_min = XFS_LEGACY_TIME_MIN; |
---|
| 1531 | + sb->s_time_max = XFS_LEGACY_TIME_MAX; |
---|
| 1532 | + } |
---|
| 1533 | + trace_xfs_inode_timestamp_range(mp, sb->s_time_min, sb->s_time_max); |
---|
| 1534 | + sb->s_iflags |= SB_I_CGROUPWB; |
---|
| 1535 | + |
---|
| 1536 | + set_posix_acl_flag(sb); |
---|
| 1537 | + |
---|
| 1538 | + /* version 5 superblocks support inode version counters. */ |
---|
| 1539 | + if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) |
---|
| 1540 | + sb->s_flags |= SB_I_VERSION; |
---|
| 1541 | + |
---|
| 1542 | + if (xfs_sb_version_hasbigtime(&mp->m_sb)) |
---|
| 1543 | + xfs_warn(mp, |
---|
| 1544 | + "EXPERIMENTAL big timestamp feature in use. Use at your own risk!"); |
---|
| 1545 | + |
---|
| 1546 | + if (mp->m_flags & XFS_MOUNT_DAX_ALWAYS) { |
---|
| 1547 | + bool rtdev_is_dax = false, datadev_is_dax; |
---|
| 1548 | + |
---|
| 1549 | + xfs_warn(mp, |
---|
| 1550 | + "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); |
---|
| 1551 | + |
---|
| 1552 | + datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev, |
---|
| 1553 | + sb->s_blocksize); |
---|
| 1554 | + if (mp->m_rtdev_targp) |
---|
| 1555 | + rtdev_is_dax = bdev_dax_supported( |
---|
| 1556 | + mp->m_rtdev_targp->bt_bdev, sb->s_blocksize); |
---|
| 1557 | + if (!rtdev_is_dax && !datadev_is_dax) { |
---|
| 1558 | + xfs_alert(mp, |
---|
| 1559 | + "DAX unsupported by block device. Turning off DAX."); |
---|
| 1560 | + xfs_mount_set_dax_mode(mp, XFS_DAX_NEVER); |
---|
| 1561 | + } |
---|
| 1562 | + if (xfs_sb_version_hasreflink(&mp->m_sb)) { |
---|
| 1563 | + xfs_alert(mp, |
---|
| 1564 | + "DAX and reflink cannot be used together!"); |
---|
| 1565 | + error = -EINVAL; |
---|
| 1566 | + goto out_filestream_unmount; |
---|
| 1567 | + } |
---|
| 1568 | + } |
---|
| 1569 | + |
---|
| 1570 | + if (mp->m_flags & XFS_MOUNT_DISCARD) { |
---|
| 1571 | + struct request_queue *q = bdev_get_queue(sb->s_bdev); |
---|
| 1572 | + |
---|
| 1573 | + if (!blk_queue_discard(q)) { |
---|
| 1574 | + xfs_warn(mp, "mounting with \"discard\" option, but " |
---|
| 1575 | + "the device does not support discard"); |
---|
| 1576 | + mp->m_flags &= ~XFS_MOUNT_DISCARD; |
---|
| 1577 | + } |
---|
| 1578 | + } |
---|
| 1579 | + |
---|
| 1580 | + if (xfs_sb_version_hasreflink(&mp->m_sb)) { |
---|
| 1581 | + if (mp->m_sb.sb_rblocks) { |
---|
| 1582 | + xfs_alert(mp, |
---|
| 1583 | + "reflink not compatible with realtime device!"); |
---|
| 1584 | + error = -EINVAL; |
---|
| 1585 | + goto out_filestream_unmount; |
---|
| 1586 | + } |
---|
| 1587 | + |
---|
| 1588 | + if (xfs_globals.always_cow) { |
---|
| 1589 | + xfs_info(mp, "using DEBUG-only always_cow mode."); |
---|
| 1590 | + mp->m_always_cow = true; |
---|
| 1591 | + } |
---|
| 1592 | + } |
---|
| 1593 | + |
---|
| 1594 | + if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks) { |
---|
| 1595 | + xfs_alert(mp, |
---|
| 1596 | + "reverse mapping btree not compatible with realtime device!"); |
---|
| 1597 | + error = -EINVAL; |
---|
| 1598 | + goto out_filestream_unmount; |
---|
| 1599 | + } |
---|
| 1600 | + |
---|
| 1601 | + if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) |
---|
| 1602 | + xfs_warn(mp, |
---|
| 1603 | + "EXPERIMENTAL inode btree counters feature in use. Use at your own risk!"); |
---|
| 1604 | + |
---|
| 1605 | + error = xfs_mountfs(mp); |
---|
| 1606 | + if (error) |
---|
| 1607 | + goto out_filestream_unmount; |
---|
| 1608 | + |
---|
| 1609 | + root = igrab(VFS_I(mp->m_rootip)); |
---|
| 1610 | + if (!root) { |
---|
| 1611 | + error = -ENOENT; |
---|
| 1612 | + goto out_unmount; |
---|
| 1613 | + } |
---|
| 1614 | + sb->s_root = d_make_root(root); |
---|
| 1615 | + if (!sb->s_root) { |
---|
| 1616 | + error = -ENOMEM; |
---|
| 1617 | + goto out_unmount; |
---|
| 1618 | + } |
---|
| 1619 | + |
---|
| 1620 | + return 0; |
---|
| 1621 | + |
---|
| 1622 | + out_filestream_unmount: |
---|
| 1623 | + xfs_filestream_unmount(mp); |
---|
| 1624 | + out_free_sb: |
---|
| 1625 | + xfs_freesb(mp); |
---|
| 1626 | + out_free_stats: |
---|
| 1627 | + free_percpu(mp->m_stats.xs_stats); |
---|
| 1628 | + out_destroy_counters: |
---|
| 1629 | + xfs_destroy_percpu_counters(mp); |
---|
| 1630 | + out_destroy_workqueues: |
---|
| 1631 | + xfs_destroy_mount_workqueues(mp); |
---|
| 1632 | + out_close_devices: |
---|
| 1633 | + xfs_close_devices(mp); |
---|
| 1634 | + out_free_names: |
---|
| 1635 | + sb->s_fs_info = NULL; |
---|
| 1636 | + xfs_mount_free(mp); |
---|
| 1637 | + return error; |
---|
| 1638 | + |
---|
| 1639 | + out_unmount: |
---|
| 1640 | + xfs_filestream_unmount(mp); |
---|
| 1641 | + xfs_unmountfs(mp); |
---|
| 1642 | + goto out_free_sb; |
---|
| 1643 | +} |
---|
| 1644 | + |
---|
| 1645 | +static int |
---|
| 1646 | +xfs_fc_get_tree( |
---|
| 1647 | + struct fs_context *fc) |
---|
| 1648 | +{ |
---|
| 1649 | + return get_tree_bdev(fc, xfs_fc_fill_super); |
---|
| 1650 | +} |
---|
| 1651 | + |
---|
| 1652 | +static int |
---|
| 1653 | +xfs_remount_rw( |
---|
| 1654 | + struct xfs_mount *mp) |
---|
| 1655 | +{ |
---|
| 1656 | + struct xfs_sb *sbp = &mp->m_sb; |
---|
| 1657 | + int error; |
---|
| 1658 | + |
---|
| 1659 | + if (mp->m_flags & XFS_MOUNT_NORECOVERY) { |
---|
| 1660 | + xfs_warn(mp, |
---|
| 1661 | + "ro->rw transition prohibited on norecovery mount"); |
---|
| 1662 | + return -EINVAL; |
---|
| 1663 | + } |
---|
| 1664 | + |
---|
| 1665 | + if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && |
---|
| 1666 | + xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { |
---|
| 1667 | + xfs_warn(mp, |
---|
| 1668 | + "ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem", |
---|
| 1669 | + (sbp->sb_features_ro_compat & |
---|
| 1670 | + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); |
---|
| 1671 | + return -EINVAL; |
---|
| 1672 | + } |
---|
| 1673 | + |
---|
| 1674 | + mp->m_flags &= ~XFS_MOUNT_RDONLY; |
---|
| 1675 | + |
---|
| 1676 | + /* |
---|
| 1677 | + * If this is the first remount to writeable state we might have some |
---|
| 1678 | + * superblock changes to update. |
---|
| 1679 | + */ |
---|
| 1680 | + if (mp->m_update_sb) { |
---|
| 1681 | + error = xfs_sync_sb(mp, false); |
---|
| 1682 | + if (error) { |
---|
| 1683 | + xfs_warn(mp, "failed to write sb changes"); |
---|
| 1684 | + return error; |
---|
| 1685 | + } |
---|
| 1686 | + mp->m_update_sb = false; |
---|
| 1687 | + } |
---|
| 1688 | + |
---|
| 1689 | + /* |
---|
| 1690 | + * Fill out the reserve pool if it is empty. Use the stashed value if |
---|
| 1691 | + * it is non-zero, otherwise go with the default. |
---|
| 1692 | + */ |
---|
| 1693 | + xfs_restore_resvblks(mp); |
---|
| 1694 | + xfs_log_work_queue(mp); |
---|
| 1695 | + |
---|
| 1696 | + /* Recover any CoW blocks that never got remapped. */ |
---|
| 1697 | + error = xfs_reflink_recover_cow(mp); |
---|
| 1698 | + if (error) { |
---|
| 1699 | + xfs_err(mp, |
---|
| 1700 | + "Error %d recovering leftover CoW allocations.", error); |
---|
| 1701 | + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
| 1702 | + return error; |
---|
| 1703 | + } |
---|
| 1704 | + xfs_start_block_reaping(mp); |
---|
| 1705 | + |
---|
| 1706 | + /* Create the per-AG metadata reservation pool .*/ |
---|
| 1707 | + error = xfs_fs_reserve_ag_blocks(mp); |
---|
| 1708 | + if (error && error != -ENOSPC) |
---|
| 1709 | + return error; |
---|
| 1710 | + |
---|
| 1711 | + return 0; |
---|
| 1712 | +} |
---|
| 1713 | + |
---|
| 1714 | +static int |
---|
| 1715 | +xfs_remount_ro( |
---|
| 1716 | + struct xfs_mount *mp) |
---|
| 1717 | +{ |
---|
| 1718 | + struct xfs_eofblocks eofb = { |
---|
| 1719 | + .eof_flags = XFS_EOF_FLAGS_SYNC, |
---|
| 1720 | + }; |
---|
| 1721 | + int error; |
---|
| 1722 | + |
---|
| 1723 | + /* Flush all the dirty data to disk. */ |
---|
| 1724 | + error = sync_filesystem(mp->m_super); |
---|
| 1725 | + if (error) |
---|
| 1726 | + return error; |
---|
| 1727 | + |
---|
| 1728 | + /* |
---|
| 1729 | + * Cancel background eofb scanning so it cannot race with the final |
---|
| 1730 | + * log force+buftarg wait and deadlock the remount. |
---|
| 1731 | + */ |
---|
| 1732 | + xfs_stop_block_reaping(mp); |
---|
| 1733 | + |
---|
| 1734 | + /* |
---|
| 1735 | + * Clear out all remaining COW staging extents and speculative post-EOF |
---|
| 1736 | + * preallocations so that we don't leave inodes requiring inactivation |
---|
| 1737 | + * cleanups during reclaim on a read-only mount. We must process every |
---|
| 1738 | + * cached inode, so this requires a synchronous cache scan. |
---|
| 1739 | + */ |
---|
| 1740 | + error = xfs_icache_free_cowblocks(mp, &eofb); |
---|
| 1741 | + if (error) { |
---|
| 1742 | + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
| 1743 | + return error; |
---|
| 1744 | + } |
---|
| 1745 | + |
---|
| 1746 | + /* Free the per-AG metadata reservation pool. */ |
---|
| 1747 | + error = xfs_fs_unreserve_ag_blocks(mp); |
---|
| 1748 | + if (error) { |
---|
| 1749 | + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
---|
| 1750 | + return error; |
---|
| 1751 | + } |
---|
| 1752 | + |
---|
| 1753 | + /* |
---|
| 1754 | + * Before we sync the metadata, we need to free up the reserve block |
---|
| 1755 | + * pool so that the used block count in the superblock on disk is |
---|
| 1756 | + * correct at the end of the remount. Stash the current* reserve pool |
---|
| 1757 | + * size so that if we get remounted rw, we can return it to the same |
---|
| 1758 | + * size. |
---|
| 1759 | + */ |
---|
| 1760 | + xfs_save_resvblks(mp); |
---|
| 1761 | + |
---|
| 1762 | + xfs_quiesce_attr(mp); |
---|
| 1763 | + mp->m_flags |= XFS_MOUNT_RDONLY; |
---|
| 1764 | + |
---|
| 1765 | + return 0; |
---|
| 1766 | +} |
---|
| 1767 | + |
---|
| 1768 | +/* |
---|
| 1769 | + * Logically we would return an error here to prevent users from believing |
---|
| 1770 | + * they might have changed mount options using remount which can't be changed. |
---|
| 1771 | + * |
---|
| 1772 | + * But unfortunately mount(8) adds all options from mtab and fstab to the mount |
---|
| 1773 | + * arguments in some cases so we can't blindly reject options, but have to |
---|
| 1774 | + * check for each specified option if it actually differs from the currently |
---|
| 1775 | + * set option and only reject it if that's the case. |
---|
| 1776 | + * |
---|
| 1777 | + * Until that is implemented we return success for every remount request, and |
---|
| 1778 | + * silently ignore all options that we can't actually change. |
---|
| 1779 | + */ |
---|
| 1780 | +static int |
---|
| 1781 | +xfs_fc_reconfigure( |
---|
| 1782 | + struct fs_context *fc) |
---|
| 1783 | +{ |
---|
| 1784 | + struct xfs_mount *mp = XFS_M(fc->root->d_sb); |
---|
| 1785 | + struct xfs_mount *new_mp = fc->s_fs_info; |
---|
| 1786 | + xfs_sb_t *sbp = &mp->m_sb; |
---|
| 1787 | + int flags = fc->sb_flags; |
---|
| 1788 | + int error; |
---|
| 1789 | + |
---|
| 1790 | + /* version 5 superblocks always support version counters. */ |
---|
| 1791 | + if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) |
---|
| 1792 | + fc->sb_flags |= SB_I_VERSION; |
---|
| 1793 | + |
---|
| 1794 | + error = xfs_fc_validate_params(new_mp); |
---|
| 1795 | + if (error) |
---|
| 1796 | + return error; |
---|
| 1797 | + |
---|
| 1798 | + /* inode32 -> inode64 */ |
---|
| 1799 | + if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && |
---|
| 1800 | + !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) { |
---|
| 1801 | + mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
---|
| 1802 | + mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); |
---|
| 1803 | + } |
---|
| 1804 | + |
---|
| 1805 | + /* inode64 -> inode32 */ |
---|
| 1806 | + if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) && |
---|
| 1807 | + (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) { |
---|
| 1808 | + mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
---|
| 1809 | + mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); |
---|
| 1810 | + } |
---|
| 1811 | + |
---|
| 1812 | + /* ro -> rw */ |
---|
| 1813 | + if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) { |
---|
| 1814 | + error = xfs_remount_rw(mp); |
---|
| 1815 | + if (error) |
---|
| 1816 | + return error; |
---|
| 1817 | + } |
---|
| 1818 | + |
---|
| 1819 | + /* rw -> ro */ |
---|
| 1820 | + if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) { |
---|
| 1821 | + error = xfs_remount_ro(mp); |
---|
| 1822 | + if (error) |
---|
| 1823 | + return error; |
---|
| 1824 | + } |
---|
| 1825 | + |
---|
| 1826 | + return 0; |
---|
| 1827 | +} |
---|
| 1828 | + |
---|
| 1829 | +static void xfs_fc_free( |
---|
| 1830 | + struct fs_context *fc) |
---|
| 1831 | +{ |
---|
| 1832 | + struct xfs_mount *mp = fc->s_fs_info; |
---|
| 1833 | + |
---|
| 1834 | + /* |
---|
| 1835 | + * mp is stored in the fs_context when it is initialized. |
---|
| 1836 | + * mp is transferred to the superblock on a successful mount, |
---|
| 1837 | + * but if an error occurs before the transfer we have to free |
---|
| 1838 | + * it here. |
---|
| 1839 | + */ |
---|
| 1840 | + if (mp) |
---|
| 1841 | + xfs_mount_free(mp); |
---|
| 1842 | +} |
---|
| 1843 | + |
---|
| 1844 | +static const struct fs_context_operations xfs_context_ops = { |
---|
| 1845 | + .parse_param = xfs_fc_parse_param, |
---|
| 1846 | + .get_tree = xfs_fc_get_tree, |
---|
| 1847 | + .reconfigure = xfs_fc_reconfigure, |
---|
| 1848 | + .free = xfs_fc_free, |
---|
| 1849 | +}; |
---|
| 1850 | + |
---|
| 1851 | +static int xfs_init_fs_context( |
---|
| 1852 | + struct fs_context *fc) |
---|
| 1853 | +{ |
---|
| 1854 | + struct xfs_mount *mp; |
---|
| 1855 | + |
---|
| 1856 | + mp = kmem_alloc(sizeof(struct xfs_mount), KM_ZERO); |
---|
| 1857 | + if (!mp) |
---|
| 1858 | + return -ENOMEM; |
---|
| 1859 | + |
---|
| 1860 | + spin_lock_init(&mp->m_sb_lock); |
---|
| 1861 | + spin_lock_init(&mp->m_agirotor_lock); |
---|
| 1862 | + INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); |
---|
| 1863 | + spin_lock_init(&mp->m_perag_lock); |
---|
| 1864 | + mutex_init(&mp->m_growlock); |
---|
| 1865 | + INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker); |
---|
| 1866 | + INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); |
---|
| 1867 | + INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); |
---|
| 1868 | + INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker); |
---|
| 1869 | + mp->m_kobj.kobject.kset = xfs_kset; |
---|
| 1870 | + /* |
---|
| 1871 | + * We don't create the finobt per-ag space reservation until after log |
---|
| 1872 | + * recovery, so we must set this to true so that an ifree transaction |
---|
| 1873 | + * started during log recovery will not depend on space reservations |
---|
| 1874 | + * for finobt expansion. |
---|
| 1875 | + */ |
---|
| 1876 | + mp->m_finobt_nores = true; |
---|
| 1877 | + |
---|
| 1878 | + /* |
---|
| 1879 | + * These can be overridden by the mount option parsing. |
---|
| 1880 | + */ |
---|
| 1881 | + mp->m_logbufs = -1; |
---|
| 1882 | + mp->m_logbsize = -1; |
---|
| 1883 | + mp->m_allocsize_log = 16; /* 64k */ |
---|
| 1884 | + |
---|
| 1885 | + /* |
---|
| 1886 | + * Copy binary VFS mount flags we are interested in. |
---|
| 1887 | + */ |
---|
| 1888 | + if (fc->sb_flags & SB_RDONLY) |
---|
| 1889 | + mp->m_flags |= XFS_MOUNT_RDONLY; |
---|
| 1890 | + if (fc->sb_flags & SB_DIRSYNC) |
---|
| 1891 | + mp->m_flags |= XFS_MOUNT_DIRSYNC; |
---|
| 1892 | + if (fc->sb_flags & SB_SYNCHRONOUS) |
---|
| 1893 | + mp->m_flags |= XFS_MOUNT_WSYNC; |
---|
| 1894 | + |
---|
| 1895 | + fc->s_fs_info = mp; |
---|
| 1896 | + fc->ops = &xfs_context_ops; |
---|
| 1897 | + |
---|
| 1898 | + return 0; |
---|
| 1899 | +} |
---|
| 1900 | + |
---|
1832 | 1901 | static struct file_system_type xfs_fs_type = { |
---|
1833 | 1902 | .owner = THIS_MODULE, |
---|
1834 | 1903 | .name = "xfs", |
---|
1835 | | - .mount = xfs_fs_mount, |
---|
| 1904 | + .init_fs_context = xfs_init_fs_context, |
---|
| 1905 | + .parameters = xfs_fs_parameters, |
---|
1836 | 1906 | .kill_sb = kill_block_super, |
---|
1837 | 1907 | .fs_flags = FS_REQUIRES_DEV, |
---|
1838 | 1908 | }; |
---|
.. | .. |
---|
1841 | 1911 | STATIC int __init |
---|
1842 | 1912 | xfs_init_zones(void) |
---|
1843 | 1913 | { |
---|
1844 | | - if (bioset_init(&xfs_ioend_bioset, 4 * (PAGE_SIZE / SECTOR_SIZE), |
---|
1845 | | - offsetof(struct xfs_ioend, io_inline_bio), |
---|
1846 | | - BIOSET_NEED_BVECS)) |
---|
| 1914 | + xfs_log_ticket_zone = kmem_cache_create("xfs_log_ticket", |
---|
| 1915 | + sizeof(struct xlog_ticket), |
---|
| 1916 | + 0, 0, NULL); |
---|
| 1917 | + if (!xfs_log_ticket_zone) |
---|
1847 | 1918 | goto out; |
---|
1848 | 1919 | |
---|
1849 | | - xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), |
---|
1850 | | - "xfs_log_ticket"); |
---|
1851 | | - if (!xfs_log_ticket_zone) |
---|
1852 | | - goto out_free_ioend_bioset; |
---|
1853 | | - |
---|
1854 | | - xfs_bmap_free_item_zone = kmem_zone_init( |
---|
1855 | | - sizeof(struct xfs_extent_free_item), |
---|
1856 | | - "xfs_bmap_free_item"); |
---|
| 1920 | + xfs_bmap_free_item_zone = kmem_cache_create("xfs_bmap_free_item", |
---|
| 1921 | + sizeof(struct xfs_extent_free_item), |
---|
| 1922 | + 0, 0, NULL); |
---|
1857 | 1923 | if (!xfs_bmap_free_item_zone) |
---|
1858 | 1924 | goto out_destroy_log_ticket_zone; |
---|
1859 | 1925 | |
---|
1860 | | - xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), |
---|
1861 | | - "xfs_btree_cur"); |
---|
| 1926 | + xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur", |
---|
| 1927 | + sizeof(struct xfs_btree_cur), |
---|
| 1928 | + 0, 0, NULL); |
---|
1862 | 1929 | if (!xfs_btree_cur_zone) |
---|
1863 | 1930 | goto out_destroy_bmap_free_item_zone; |
---|
1864 | 1931 | |
---|
1865 | | - xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), |
---|
1866 | | - "xfs_da_state"); |
---|
| 1932 | + xfs_da_state_zone = kmem_cache_create("xfs_da_state", |
---|
| 1933 | + sizeof(struct xfs_da_state), |
---|
| 1934 | + 0, 0, NULL); |
---|
1867 | 1935 | if (!xfs_da_state_zone) |
---|
1868 | 1936 | goto out_destroy_btree_cur_zone; |
---|
1869 | 1937 | |
---|
1870 | | - xfs_ifork_zone = kmem_zone_init(sizeof(struct xfs_ifork), "xfs_ifork"); |
---|
| 1938 | + xfs_ifork_zone = kmem_cache_create("xfs_ifork", |
---|
| 1939 | + sizeof(struct xfs_ifork), |
---|
| 1940 | + 0, 0, NULL); |
---|
1871 | 1941 | if (!xfs_ifork_zone) |
---|
1872 | 1942 | goto out_destroy_da_state_zone; |
---|
1873 | 1943 | |
---|
1874 | | - xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); |
---|
| 1944 | + xfs_trans_zone = kmem_cache_create("xfs_trans", |
---|
| 1945 | + sizeof(struct xfs_trans), |
---|
| 1946 | + 0, 0, NULL); |
---|
1875 | 1947 | if (!xfs_trans_zone) |
---|
1876 | 1948 | goto out_destroy_ifork_zone; |
---|
1877 | 1949 | |
---|
.. | .. |
---|
1881 | 1953 | * size possible under XFS. This wastes a little bit of memory, |
---|
1882 | 1954 | * but it is much faster. |
---|
1883 | 1955 | */ |
---|
1884 | | - xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), |
---|
1885 | | - "xfs_buf_item"); |
---|
| 1956 | + xfs_buf_item_zone = kmem_cache_create("xfs_buf_item", |
---|
| 1957 | + sizeof(struct xfs_buf_log_item), |
---|
| 1958 | + 0, 0, NULL); |
---|
1886 | 1959 | if (!xfs_buf_item_zone) |
---|
1887 | 1960 | goto out_destroy_trans_zone; |
---|
1888 | 1961 | |
---|
1889 | | - xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + |
---|
1890 | | - ((XFS_EFD_MAX_FAST_EXTENTS - 1) * |
---|
1891 | | - sizeof(xfs_extent_t))), "xfs_efd_item"); |
---|
| 1962 | + xfs_efd_zone = kmem_cache_create("xfs_efd_item", |
---|
| 1963 | + (sizeof(struct xfs_efd_log_item) + |
---|
| 1964 | + (XFS_EFD_MAX_FAST_EXTENTS - 1) * |
---|
| 1965 | + sizeof(struct xfs_extent)), |
---|
| 1966 | + 0, 0, NULL); |
---|
1892 | 1967 | if (!xfs_efd_zone) |
---|
1893 | 1968 | goto out_destroy_buf_item_zone; |
---|
1894 | 1969 | |
---|
1895 | | - xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + |
---|
1896 | | - ((XFS_EFI_MAX_FAST_EXTENTS - 1) * |
---|
1897 | | - sizeof(xfs_extent_t))), "xfs_efi_item"); |
---|
| 1970 | + xfs_efi_zone = kmem_cache_create("xfs_efi_item", |
---|
| 1971 | + (sizeof(struct xfs_efi_log_item) + |
---|
| 1972 | + (XFS_EFI_MAX_FAST_EXTENTS - 1) * |
---|
| 1973 | + sizeof(struct xfs_extent)), |
---|
| 1974 | + 0, 0, NULL); |
---|
1898 | 1975 | if (!xfs_efi_zone) |
---|
1899 | 1976 | goto out_destroy_efd_zone; |
---|
1900 | 1977 | |
---|
1901 | | - xfs_inode_zone = |
---|
1902 | | - kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", |
---|
1903 | | - KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD | |
---|
1904 | | - KM_ZONE_ACCOUNT, xfs_fs_inode_init_once); |
---|
| 1978 | + xfs_inode_zone = kmem_cache_create("xfs_inode", |
---|
| 1979 | + sizeof(struct xfs_inode), 0, |
---|
| 1980 | + (SLAB_HWCACHE_ALIGN | |
---|
| 1981 | + SLAB_RECLAIM_ACCOUNT | |
---|
| 1982 | + SLAB_MEM_SPREAD | SLAB_ACCOUNT), |
---|
| 1983 | + xfs_fs_inode_init_once); |
---|
1905 | 1984 | if (!xfs_inode_zone) |
---|
1906 | 1985 | goto out_destroy_efi_zone; |
---|
1907 | 1986 | |
---|
1908 | | - xfs_ili_zone = |
---|
1909 | | - kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", |
---|
1910 | | - KM_ZONE_SPREAD, NULL); |
---|
| 1987 | + xfs_ili_zone = kmem_cache_create("xfs_ili", |
---|
| 1988 | + sizeof(struct xfs_inode_log_item), 0, |
---|
| 1989 | + SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, |
---|
| 1990 | + NULL); |
---|
1911 | 1991 | if (!xfs_ili_zone) |
---|
1912 | 1992 | goto out_destroy_inode_zone; |
---|
1913 | | - xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item), |
---|
1914 | | - "xfs_icr"); |
---|
| 1993 | + |
---|
| 1994 | + xfs_icreate_zone = kmem_cache_create("xfs_icr", |
---|
| 1995 | + sizeof(struct xfs_icreate_item), |
---|
| 1996 | + 0, 0, NULL); |
---|
1915 | 1997 | if (!xfs_icreate_zone) |
---|
1916 | 1998 | goto out_destroy_ili_zone; |
---|
1917 | 1999 | |
---|
1918 | | - xfs_rud_zone = kmem_zone_init(sizeof(struct xfs_rud_log_item), |
---|
1919 | | - "xfs_rud_item"); |
---|
| 2000 | + xfs_rud_zone = kmem_cache_create("xfs_rud_item", |
---|
| 2001 | + sizeof(struct xfs_rud_log_item), |
---|
| 2002 | + 0, 0, NULL); |
---|
1920 | 2003 | if (!xfs_rud_zone) |
---|
1921 | 2004 | goto out_destroy_icreate_zone; |
---|
1922 | 2005 | |
---|
1923 | | - xfs_rui_zone = kmem_zone_init( |
---|
| 2006 | + xfs_rui_zone = kmem_cache_create("xfs_rui_item", |
---|
1924 | 2007 | xfs_rui_log_item_sizeof(XFS_RUI_MAX_FAST_EXTENTS), |
---|
1925 | | - "xfs_rui_item"); |
---|
| 2008 | + 0, 0, NULL); |
---|
1926 | 2009 | if (!xfs_rui_zone) |
---|
1927 | 2010 | goto out_destroy_rud_zone; |
---|
1928 | 2011 | |
---|
1929 | | - xfs_cud_zone = kmem_zone_init(sizeof(struct xfs_cud_log_item), |
---|
1930 | | - "xfs_cud_item"); |
---|
| 2012 | + xfs_cud_zone = kmem_cache_create("xfs_cud_item", |
---|
| 2013 | + sizeof(struct xfs_cud_log_item), |
---|
| 2014 | + 0, 0, NULL); |
---|
1931 | 2015 | if (!xfs_cud_zone) |
---|
1932 | 2016 | goto out_destroy_rui_zone; |
---|
1933 | 2017 | |
---|
1934 | | - xfs_cui_zone = kmem_zone_init( |
---|
| 2018 | + xfs_cui_zone = kmem_cache_create("xfs_cui_item", |
---|
1935 | 2019 | xfs_cui_log_item_sizeof(XFS_CUI_MAX_FAST_EXTENTS), |
---|
1936 | | - "xfs_cui_item"); |
---|
| 2020 | + 0, 0, NULL); |
---|
1937 | 2021 | if (!xfs_cui_zone) |
---|
1938 | 2022 | goto out_destroy_cud_zone; |
---|
1939 | 2023 | |
---|
1940 | | - xfs_bud_zone = kmem_zone_init(sizeof(struct xfs_bud_log_item), |
---|
1941 | | - "xfs_bud_item"); |
---|
| 2024 | + xfs_bud_zone = kmem_cache_create("xfs_bud_item", |
---|
| 2025 | + sizeof(struct xfs_bud_log_item), |
---|
| 2026 | + 0, 0, NULL); |
---|
1942 | 2027 | if (!xfs_bud_zone) |
---|
1943 | 2028 | goto out_destroy_cui_zone; |
---|
1944 | 2029 | |
---|
1945 | | - xfs_bui_zone = kmem_zone_init( |
---|
| 2030 | + xfs_bui_zone = kmem_cache_create("xfs_bui_item", |
---|
1946 | 2031 | xfs_bui_log_item_sizeof(XFS_BUI_MAX_FAST_EXTENTS), |
---|
1947 | | - "xfs_bui_item"); |
---|
| 2032 | + 0, 0, NULL); |
---|
1948 | 2033 | if (!xfs_bui_zone) |
---|
1949 | 2034 | goto out_destroy_bud_zone; |
---|
1950 | 2035 | |
---|
1951 | 2036 | return 0; |
---|
1952 | 2037 | |
---|
1953 | 2038 | out_destroy_bud_zone: |
---|
1954 | | - kmem_zone_destroy(xfs_bud_zone); |
---|
| 2039 | + kmem_cache_destroy(xfs_bud_zone); |
---|
1955 | 2040 | out_destroy_cui_zone: |
---|
1956 | | - kmem_zone_destroy(xfs_cui_zone); |
---|
| 2041 | + kmem_cache_destroy(xfs_cui_zone); |
---|
1957 | 2042 | out_destroy_cud_zone: |
---|
1958 | | - kmem_zone_destroy(xfs_cud_zone); |
---|
| 2043 | + kmem_cache_destroy(xfs_cud_zone); |
---|
1959 | 2044 | out_destroy_rui_zone: |
---|
1960 | | - kmem_zone_destroy(xfs_rui_zone); |
---|
| 2045 | + kmem_cache_destroy(xfs_rui_zone); |
---|
1961 | 2046 | out_destroy_rud_zone: |
---|
1962 | | - kmem_zone_destroy(xfs_rud_zone); |
---|
| 2047 | + kmem_cache_destroy(xfs_rud_zone); |
---|
1963 | 2048 | out_destroy_icreate_zone: |
---|
1964 | | - kmem_zone_destroy(xfs_icreate_zone); |
---|
| 2049 | + kmem_cache_destroy(xfs_icreate_zone); |
---|
1965 | 2050 | out_destroy_ili_zone: |
---|
1966 | | - kmem_zone_destroy(xfs_ili_zone); |
---|
| 2051 | + kmem_cache_destroy(xfs_ili_zone); |
---|
1967 | 2052 | out_destroy_inode_zone: |
---|
1968 | | - kmem_zone_destroy(xfs_inode_zone); |
---|
| 2053 | + kmem_cache_destroy(xfs_inode_zone); |
---|
1969 | 2054 | out_destroy_efi_zone: |
---|
1970 | | - kmem_zone_destroy(xfs_efi_zone); |
---|
| 2055 | + kmem_cache_destroy(xfs_efi_zone); |
---|
1971 | 2056 | out_destroy_efd_zone: |
---|
1972 | | - kmem_zone_destroy(xfs_efd_zone); |
---|
| 2057 | + kmem_cache_destroy(xfs_efd_zone); |
---|
1973 | 2058 | out_destroy_buf_item_zone: |
---|
1974 | | - kmem_zone_destroy(xfs_buf_item_zone); |
---|
| 2059 | + kmem_cache_destroy(xfs_buf_item_zone); |
---|
1975 | 2060 | out_destroy_trans_zone: |
---|
1976 | | - kmem_zone_destroy(xfs_trans_zone); |
---|
| 2061 | + kmem_cache_destroy(xfs_trans_zone); |
---|
1977 | 2062 | out_destroy_ifork_zone: |
---|
1978 | | - kmem_zone_destroy(xfs_ifork_zone); |
---|
| 2063 | + kmem_cache_destroy(xfs_ifork_zone); |
---|
1979 | 2064 | out_destroy_da_state_zone: |
---|
1980 | | - kmem_zone_destroy(xfs_da_state_zone); |
---|
| 2065 | + kmem_cache_destroy(xfs_da_state_zone); |
---|
1981 | 2066 | out_destroy_btree_cur_zone: |
---|
1982 | | - kmem_zone_destroy(xfs_btree_cur_zone); |
---|
| 2067 | + kmem_cache_destroy(xfs_btree_cur_zone); |
---|
1983 | 2068 | out_destroy_bmap_free_item_zone: |
---|
1984 | | - kmem_zone_destroy(xfs_bmap_free_item_zone); |
---|
| 2069 | + kmem_cache_destroy(xfs_bmap_free_item_zone); |
---|
1985 | 2070 | out_destroy_log_ticket_zone: |
---|
1986 | | - kmem_zone_destroy(xfs_log_ticket_zone); |
---|
1987 | | - out_free_ioend_bioset: |
---|
1988 | | - bioset_exit(&xfs_ioend_bioset); |
---|
| 2071 | + kmem_cache_destroy(xfs_log_ticket_zone); |
---|
1989 | 2072 | out: |
---|
1990 | 2073 | return -ENOMEM; |
---|
1991 | 2074 | } |
---|
.. | .. |
---|
1998 | 2081 | * destroy caches. |
---|
1999 | 2082 | */ |
---|
2000 | 2083 | rcu_barrier(); |
---|
2001 | | - kmem_zone_destroy(xfs_bui_zone); |
---|
2002 | | - kmem_zone_destroy(xfs_bud_zone); |
---|
2003 | | - kmem_zone_destroy(xfs_cui_zone); |
---|
2004 | | - kmem_zone_destroy(xfs_cud_zone); |
---|
2005 | | - kmem_zone_destroy(xfs_rui_zone); |
---|
2006 | | - kmem_zone_destroy(xfs_rud_zone); |
---|
2007 | | - kmem_zone_destroy(xfs_icreate_zone); |
---|
2008 | | - kmem_zone_destroy(xfs_ili_zone); |
---|
2009 | | - kmem_zone_destroy(xfs_inode_zone); |
---|
2010 | | - kmem_zone_destroy(xfs_efi_zone); |
---|
2011 | | - kmem_zone_destroy(xfs_efd_zone); |
---|
2012 | | - kmem_zone_destroy(xfs_buf_item_zone); |
---|
2013 | | - kmem_zone_destroy(xfs_trans_zone); |
---|
2014 | | - kmem_zone_destroy(xfs_ifork_zone); |
---|
2015 | | - kmem_zone_destroy(xfs_da_state_zone); |
---|
2016 | | - kmem_zone_destroy(xfs_btree_cur_zone); |
---|
2017 | | - kmem_zone_destroy(xfs_bmap_free_item_zone); |
---|
2018 | | - kmem_zone_destroy(xfs_log_ticket_zone); |
---|
2019 | | - bioset_exit(&xfs_ioend_bioset); |
---|
| 2084 | + kmem_cache_destroy(xfs_bui_zone); |
---|
| 2085 | + kmem_cache_destroy(xfs_bud_zone); |
---|
| 2086 | + kmem_cache_destroy(xfs_cui_zone); |
---|
| 2087 | + kmem_cache_destroy(xfs_cud_zone); |
---|
| 2088 | + kmem_cache_destroy(xfs_rui_zone); |
---|
| 2089 | + kmem_cache_destroy(xfs_rud_zone); |
---|
| 2090 | + kmem_cache_destroy(xfs_icreate_zone); |
---|
| 2091 | + kmem_cache_destroy(xfs_ili_zone); |
---|
| 2092 | + kmem_cache_destroy(xfs_inode_zone); |
---|
| 2093 | + kmem_cache_destroy(xfs_efi_zone); |
---|
| 2094 | + kmem_cache_destroy(xfs_efd_zone); |
---|
| 2095 | + kmem_cache_destroy(xfs_buf_item_zone); |
---|
| 2096 | + kmem_cache_destroy(xfs_trans_zone); |
---|
| 2097 | + kmem_cache_destroy(xfs_ifork_zone); |
---|
| 2098 | + kmem_cache_destroy(xfs_da_state_zone); |
---|
| 2099 | + kmem_cache_destroy(xfs_btree_cur_zone); |
---|
| 2100 | + kmem_cache_destroy(xfs_bmap_free_item_zone); |
---|
| 2101 | + kmem_cache_destroy(xfs_log_ticket_zone); |
---|
2020 | 2102 | } |
---|
2021 | 2103 | |
---|
2022 | 2104 | STATIC int __init |
---|
.. | .. |
---|
2059 | 2141 | |
---|
2060 | 2142 | printk(KERN_INFO XFS_VERSION_STRING " with " |
---|
2061 | 2143 | XFS_BUILD_OPTIONS " enabled\n"); |
---|
2062 | | - |
---|
2063 | | - xfs_extent_free_init_defer_op(); |
---|
2064 | | - xfs_rmap_update_init_defer_op(); |
---|
2065 | | - xfs_refcount_update_init_defer_op(); |
---|
2066 | | - xfs_bmap_update_init_defer_op(); |
---|
2067 | 2144 | |
---|
2068 | 2145 | xfs_dir_startup(); |
---|
2069 | 2146 | |
---|
.. | .. |
---|
2180 | 2257 | MODULE_AUTHOR("Silicon Graphics, Inc."); |
---|
2181 | 2258 | MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled"); |
---|
2182 | 2259 | MODULE_LICENSE("GPL"); |
---|
| 2260 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
---|