blob: 651ce767b55d8241e283b3001d7fc9e6d803b317 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 *
4 * Trivial changes by Alan Cox to add the LFS fixes
5 *
6 * Trivial Changes:
7 * Rights granted to Hans Reiser to redistribute under other terms providing
8 * he accepts all liability including but not limited to patent, fitness
9 * for purpose, and direct or indirect claims arising from failure to perform.
10 *
11 * NO WARRANTY
12 */
13
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090015#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/vmalloc.h>
17#include <linux/time.h>
18#include <asm/uaccess.h>
Al Virof466c6f2012-03-17 01:16:43 -040019#include "reiserfs.h"
Al Viroa3063ab2012-03-17 01:03:10 -040020#include "acl.h"
Al Viroc45ac882012-03-17 00:59:06 -040021#include "xattr.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/init.h>
23#include <linux/blkdev.h>
24#include <linux/buffer_head.h>
Christoph Hellwiga5694252007-07-17 04:04:28 -070025#include <linux/exportfs.h>
Jan Kara74abb982008-07-25 01:46:51 -070026#include <linux/quotaops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/vfs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/mount.h>
29#include <linux/namei.h>
Coly Li651d0622009-04-02 16:59:41 -070030#include <linux/crc32.h>
Jan Karac3aa0772011-12-21 20:17:10 +010031#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33struct file_system_type reiserfs_fs_type;
34
35static const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
36static const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
37static const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
38
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070039int is_reiserfs_3_5(struct reiserfs_super_block *rs)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070041 return !strncmp(rs->s_v1.s_magic, reiserfs_3_5_magic_string,
42 strlen(reiserfs_3_5_magic_string));
Linus Torvalds1da177e2005-04-16 15:20:36 -070043}
44
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070045int is_reiserfs_3_6(struct reiserfs_super_block *rs)
Linus Torvalds1da177e2005-04-16 15:20:36 -070046{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070047 return !strncmp(rs->s_v1.s_magic, reiserfs_3_6_magic_string,
48 strlen(reiserfs_3_6_magic_string));
Linus Torvalds1da177e2005-04-16 15:20:36 -070049}
50
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070051int is_reiserfs_jr(struct reiserfs_super_block *rs)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070053 return !strncmp(rs->s_v1.s_magic, reiserfs_jr_magic_string,
54 strlen(reiserfs_jr_magic_string));
Linus Torvalds1da177e2005-04-16 15:20:36 -070055}
56
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070057static int is_any_reiserfs_magic_string(struct reiserfs_super_block *rs)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070059 return (is_reiserfs_3_5(rs) || is_reiserfs_3_6(rs) ||
60 is_reiserfs_jr(rs));
Linus Torvalds1da177e2005-04-16 15:20:36 -070061}
62
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070063static int reiserfs_remount(struct super_block *s, int *flags, char *data);
David Howells726c3342006-06-23 02:02:58 -070064static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf);
Jan Karac3aa0772011-12-21 20:17:10 +010065void show_alloc_options(struct seq_file *seq, struct super_block *s);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070067static int reiserfs_sync_fs(struct super_block *s, int wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -070068{
Christoph Hellwig5af79262009-05-05 15:41:25 +020069 struct reiserfs_transaction_handle th;
70
71 reiserfs_write_lock(s);
72 if (!journal_begin(&th, s, 1))
73 if (!journal_end_sync(&th, s, 1))
74 reiserfs_flush_old_commits(s);
Christoph Hellwig5af79262009-05-05 15:41:25 +020075 reiserfs_write_unlock(s);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070076 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070077}
78
Artem Bityutskiy033369d2012-06-01 17:18:08 +030079static void flush_old_commits(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
Artem Bityutskiy033369d2012-06-01 17:18:08 +030081 struct reiserfs_sb_info *sbi;
82 struct super_block *s;
83
84 sbi = container_of(work, struct reiserfs_sb_info, old_work.work);
85 s = sbi->s_journal->j_work_sb;
86
87 spin_lock(&sbi->old_work_lock);
88 sbi->work_queued = 0;
89 spin_unlock(&sbi->old_work_lock);
90
Linus Torvaldsbd4c6252005-07-12 20:21:28 -070091 reiserfs_sync_fs(s, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092}
93
Artem Bityutskiy033369d2012-06-01 17:18:08 +030094void reiserfs_schedule_old_flush(struct super_block *s)
95{
96 struct reiserfs_sb_info *sbi = REISERFS_SB(s);
97 unsigned long delay;
98
99 if (s->s_flags & MS_RDONLY)
100 return;
101
102 spin_lock(&sbi->old_work_lock);
103 if (!sbi->work_queued) {
104 delay = msecs_to_jiffies(dirty_writeback_interval * 10);
105 queue_delayed_work(system_long_wq, &sbi->old_work, delay);
106 sbi->work_queued = 1;
107 }
108 spin_unlock(&sbi->old_work_lock);
109}
110
111static void cancel_old_flush(struct super_block *s)
112{
113 struct reiserfs_sb_info *sbi = REISERFS_SB(s);
114
115 cancel_delayed_work_sync(&REISERFS_SB(s)->old_work);
116 spin_lock(&sbi->old_work_lock);
117 sbi->work_queued = 0;
118 spin_unlock(&sbi->old_work_lock);
119}
120
Takashi Satoc4be0c12009-01-09 16:40:58 -0800121static int reiserfs_freeze(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700123 struct reiserfs_transaction_handle th;
Artem Bityutskiy033369d2012-06-01 17:18:08 +0300124
125 cancel_old_flush(s);
126
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700127 reiserfs_write_lock(s);
128 if (!(s->s_flags & MS_RDONLY)) {
129 int err = journal_begin(&th, s, 1);
130 if (err) {
131 reiserfs_block_writes(&th);
132 } else {
133 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
134 1);
135 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
136 reiserfs_block_writes(&th);
137 journal_end_sync(&th, s, 1);
138 }
139 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700140 reiserfs_write_unlock(s);
Takashi Satoc4be0c12009-01-09 16:40:58 -0800141 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142}
143
Takashi Satoc4be0c12009-01-09 16:40:58 -0800144static int reiserfs_unfreeze(struct super_block *s)
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700145{
146 reiserfs_allow_writes(s);
Takashi Satoc4be0c12009-01-09 16:40:58 -0800147 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148}
149
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700150extern const struct in_core_key MAX_IN_CORE_KEY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152/* this is used to delete "save link" when there are no items of a
153 file it points to. It can either happen if unlink is completed but
154 "save unlink" removal, or if file has both unlink and truncate
155 pending and as unlink completes first (because key of "save link"
156 protecting unlink is bigger that a key lf "save link" which
157 protects truncate), so there left no items to make truncate
158 completion on */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700159static int remove_save_link_only(struct super_block *s,
160 struct reiserfs_key *key, int oid_free)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700162 struct reiserfs_transaction_handle th;
163 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700165 /* we are going to do one balancing */
166 err = journal_begin(&th, s, JOURNAL_PER_BALANCE_CNT);
167 if (err)
168 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700170 reiserfs_delete_solid_item(&th, NULL, key);
171 if (oid_free)
172 /* removals are protected by direct items */
173 reiserfs_release_objectid(&th, le32_to_cpu(key->k_objectid));
174
175 return journal_end(&th, s, JOURNAL_PER_BALANCE_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176}
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700177
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178#ifdef CONFIG_QUOTA
179static int reiserfs_quota_on_mount(struct super_block *, int);
180#endif
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700181
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182/* look for uncompleted unlinks and truncates and complete them */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700183static int finish_unfinished(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700185 INITIALIZE_PATH(path);
186 struct cpu_key max_cpu_key, obj_key;
Lepton Wufb46f342007-10-16 23:30:04 -0700187 struct reiserfs_key save_link_key, last_inode_key;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700188 int retval = 0;
189 struct item_head *ih;
190 struct buffer_head *bh;
191 int item_pos;
192 char *item;
193 int done;
194 struct inode *inode;
195 int truncate;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700197 int i;
198 int ms_active_set;
Jan Karaf4b113a2010-05-21 19:12:51 +0200199 int quota_enabled[MAXQUOTAS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200#endif
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700201
202 /* compose key to look for "save" links */
203 max_cpu_key.version = KEY_FORMAT_3_5;
204 max_cpu_key.on_disk_key.k_dir_id = ~0U;
205 max_cpu_key.on_disk_key.k_objectid = ~0U;
206 set_cpu_key_k_offset(&max_cpu_key, ~0U);
207 max_cpu_key.key_length = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
Lepton Wufb46f342007-10-16 23:30:04 -0700209 memset(&last_inode_key, 0, sizeof(last_inode_key));
210
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700212 /* Needed for iput() to work correctly and not trash data */
213 if (s->s_flags & MS_ACTIVE) {
214 ms_active_set = 0;
215 } else {
216 ms_active_set = 1;
217 s->s_flags |= MS_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700219 /* Turn on quotas so that they are updated correctly */
220 for (i = 0; i < MAXQUOTAS; i++) {
Jan Karaf4b113a2010-05-21 19:12:51 +0200221 quota_enabled[i] = 1;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700222 if (REISERFS_SB(s)->s_qf_names[i]) {
Jan Karaf4b113a2010-05-21 19:12:51 +0200223 int ret;
224
225 if (sb_has_quota_active(s, i)) {
226 quota_enabled[i] = 0;
227 continue;
228 }
229 ret = reiserfs_quota_on_mount(s, i);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700230 if (ret < 0)
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400231 reiserfs_warning(s, "reiserfs-2500",
232 "cannot turn on journaled "
233 "quota: error %d", ret);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700234 }
235 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700238 done = 0;
239 REISERFS_SB(s)->s_is_unlinked_ok = 1;
240 while (!retval) {
241 retval = search_item(s, &max_cpu_key, &path);
242 if (retval != ITEM_NOT_FOUND) {
Jeff Mahoney0030b642009-03-30 14:02:28 -0400243 reiserfs_error(s, "vs-2140",
244 "search_by_key returned %d", retval);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700245 break;
246 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700248 bh = get_last_bh(&path);
249 item_pos = get_item_pos(&path);
250 if (item_pos != B_NR_ITEMS(bh)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400251 reiserfs_warning(s, "vs-2060",
252 "wrong position found");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700253 break;
254 }
255 item_pos--;
256 ih = B_N_PITEM_HEAD(bh, item_pos);
257
258 if (le32_to_cpu(ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
259 /* there are no "save" links anymore */
260 break;
261
262 save_link_key = ih->ih_key;
263 if (is_indirect_le_ih(ih))
264 truncate = 1;
265 else
266 truncate = 0;
267
268 /* reiserfs_iget needs k_dirid and k_objectid only */
269 item = B_I_PITEM(bh, ih);
270 obj_key.on_disk_key.k_dir_id = le32_to_cpu(*(__le32 *) item);
271 obj_key.on_disk_key.k_objectid =
272 le32_to_cpu(ih->ih_key.k_objectid);
273 obj_key.on_disk_key.k_offset = 0;
274 obj_key.on_disk_key.k_type = 0;
275
276 pathrelse(&path);
277
278 inode = reiserfs_iget(s, &obj_key);
279 if (!inode) {
280 /* the unlink almost completed, it just did not manage to remove
281 "save" link and release objectid */
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400282 reiserfs_warning(s, "vs-2180", "iget failed for %K",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700283 &obj_key);
284 retval = remove_save_link_only(s, &save_link_key, 1);
285 continue;
286 }
287
288 if (!truncate && inode->i_nlink) {
289 /* file is not unlinked */
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400290 reiserfs_warning(s, "vs-2185",
291 "file %K is not unlinked",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700292 &obj_key);
293 retval = remove_save_link_only(s, &save_link_key, 0);
294 continue;
295 }
Christoph Hellwig871a2932010-03-03 09:05:07 -0500296 dquot_initialize(inode);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700297
298 if (truncate && S_ISDIR(inode->i_mode)) {
299 /* We got a truncate request for a dir which is impossible.
300 The only imaginable way is to execute unfinished truncate request
301 then boot into old kernel, remove the file and create dir with
302 the same key. */
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400303 reiserfs_warning(s, "green-2101",
304 "impossible truncate on a "
305 "directory %k. Please report",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700306 INODE_PKEY(inode));
307 retval = remove_save_link_only(s, &save_link_key, 0);
308 truncate = 0;
309 iput(inode);
310 continue;
311 }
312
313 if (truncate) {
314 REISERFS_I(inode)->i_flags |=
315 i_link_saved_truncate_mask;
316 /* not completed truncate found. New size was committed together
317 with "save" link */
318 reiserfs_info(s, "Truncating %k to %Ld ..",
319 INODE_PKEY(inode), inode->i_size);
320 reiserfs_truncate_file(inode,
321 0
322 /*don't update modification time */
323 );
324 retval = remove_save_link(inode, truncate);
325 } else {
326 REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
327 /* not completed unlink (rmdir) found */
328 reiserfs_info(s, "Removing %k..", INODE_PKEY(inode));
Lepton Wufb46f342007-10-16 23:30:04 -0700329 if (memcmp(&last_inode_key, INODE_PKEY(inode),
330 sizeof(last_inode_key))){
331 last_inode_key = *INODE_PKEY(inode);
332 /* removal gets completed in iput */
333 retval = 0;
334 } else {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400335 reiserfs_warning(s, "super-2189", "Dead loop "
336 "in finish_unfinished "
337 "detected, just remove "
338 "save link\n");
Lepton Wufb46f342007-10-16 23:30:04 -0700339 retval = remove_save_link_only(s,
340 &save_link_key, 0);
341 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700342 }
343
344 iput(inode);
345 printk("done\n");
346 done++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700348 REISERFS_SB(s)->s_is_unlinked_ok = 0;
349
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700351 /* Turn quotas off */
352 for (i = 0; i < MAXQUOTAS; i++) {
Jan Karaf4b113a2010-05-21 19:12:51 +0200353 if (sb_dqopt(s)->files[i] && quota_enabled[i])
Christoph Hellwig287a8092010-05-19 07:16:45 -0400354 dquot_quota_off(s, i);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700355 }
356 if (ms_active_set)
357 /* Restore the flag back */
358 s->s_flags &= ~MS_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359#endif
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700360 pathrelse(&path);
361 if (done)
362 reiserfs_info(s, "There were %d uncompleted unlinks/truncates. "
363 "Completed\n", done);
364 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365}
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700366
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367/* to protect file being unlinked from getting lost we "safe" link files
368 being unlinked. This link will be deleted in the same transaction with last
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200369 item of file. mounting the filesystem we scan all these links and remove
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 files which almost got lost */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700371void add_save_link(struct reiserfs_transaction_handle *th,
372 struct inode *inode, int truncate)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700374 INITIALIZE_PATH(path);
375 int retval;
376 struct cpu_key key;
377 struct item_head ih;
378 __le32 link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700380 BUG_ON(!th->t_trans_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700382 /* file can only get one "save link" of each kind */
383 RFALSE(truncate &&
384 (REISERFS_I(inode)->i_flags & i_link_saved_truncate_mask),
385 "saved link already exists for truncated inode %lx",
386 (long)inode->i_ino);
387 RFALSE(!truncate &&
388 (REISERFS_I(inode)->i_flags & i_link_saved_unlink_mask),
389 "saved link already exists for unlinked inode %lx",
390 (long)inode->i_ino);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700392 /* setup key of "save" link */
393 key.version = KEY_FORMAT_3_5;
394 key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
395 key.on_disk_key.k_objectid = inode->i_ino;
396 if (!truncate) {
397 /* unlink, rmdir, rename */
398 set_cpu_key_k_offset(&key, 1 + inode->i_sb->s_blocksize);
399 set_cpu_key_k_type(&key, TYPE_DIRECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700401 /* item head of "safe" link */
402 make_le_item_head(&ih, &key, key.version,
403 1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
404 4 /*length */ , 0xffff /*free space */ );
405 } else {
406 /* truncate */
407 if (S_ISDIR(inode->i_mode))
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400408 reiserfs_warning(inode->i_sb, "green-2102",
409 "Adding a truncate savelink for "
410 "a directory %k! Please report",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700411 INODE_PKEY(inode));
412 set_cpu_key_k_offset(&key, 1);
413 set_cpu_key_k_type(&key, TYPE_INDIRECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700415 /* item head of "safe" link */
416 make_le_item_head(&ih, &key, key.version, 1, TYPE_INDIRECT,
417 4 /*length */ , 0 /*free space */ );
418 }
419 key.key_length = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700421 /* look for its place in the tree */
422 retval = search_item(inode->i_sb, &key, &path);
423 if (retval != ITEM_NOT_FOUND) {
424 if (retval != -ENOSPC)
Jeff Mahoney0030b642009-03-30 14:02:28 -0400425 reiserfs_error(inode->i_sb, "vs-2100",
426 "search_by_key (%K) returned %d", &key,
427 retval);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700428 pathrelse(&path);
429 return;
430 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700432 /* body of "save" link */
433 link = INODE_PKEY(inode)->k_dir_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300435 /* put "save" link into tree, don't charge quota to anyone */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700436 retval =
437 reiserfs_insert_item(th, &path, &key, &ih, NULL, (char *)&link);
438 if (retval) {
439 if (retval != -ENOSPC)
Jeff Mahoney0030b642009-03-30 14:02:28 -0400440 reiserfs_error(inode->i_sb, "vs-2120",
441 "insert_item returned %d", retval);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700442 } else {
443 if (truncate)
444 REISERFS_I(inode)->i_flags |=
445 i_link_saved_truncate_mask;
446 else
447 REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
448 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449}
450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451/* this opens transaction unlike add_save_link */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700452int remove_save_link(struct inode *inode, int truncate)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700454 struct reiserfs_transaction_handle th;
455 struct reiserfs_key key;
456 int err;
457
458 /* we are going to do one balancing only */
459 err = journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
460 if (err)
461 return err;
462
463 /* setup key of "save" link */
464 key.k_dir_id = cpu_to_le32(MAX_KEY_OBJECTID);
465 key.k_objectid = INODE_PKEY(inode)->k_objectid;
466 if (!truncate) {
467 /* unlink, rmdir, rename */
468 set_le_key_k_offset(KEY_FORMAT_3_5, &key,
469 1 + inode->i_sb->s_blocksize);
470 set_le_key_k_type(KEY_FORMAT_3_5, &key, TYPE_DIRECT);
471 } else {
472 /* truncate */
473 set_le_key_k_offset(KEY_FORMAT_3_5, &key, 1);
474 set_le_key_k_type(KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
475 }
476
477 if ((truncate &&
478 (REISERFS_I(inode)->i_flags & i_link_saved_truncate_mask)) ||
479 (!truncate &&
480 (REISERFS_I(inode)->i_flags & i_link_saved_unlink_mask)))
481 /* don't take quota bytes from anywhere */
482 reiserfs_delete_solid_item(&th, NULL, &key);
483 if (!truncate) {
484 reiserfs_release_objectid(&th, inode->i_ino);
485 REISERFS_I(inode)->i_flags &= ~i_link_saved_unlink_mask;
486 } else
487 REISERFS_I(inode)->i_flags &= ~i_link_saved_truncate_mask;
488
489 return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490}
491
David Howellsedc666e2006-10-11 01:22:14 -0700492static void reiserfs_kill_sb(struct super_block *s)
493{
494 if (REISERFS_SB(s)) {
Jeff Mahoneya9e36da2011-12-21 21:18:43 +0100495 /*
496 * Force any pending inode evictions to occur now. Any
497 * inodes to be removed that have extended attributes
498 * associated with them need to clean them up before
499 * we can release the extended attribute root dentries.
500 * shrink_dcache_for_umount will BUG if we don't release
501 * those before it's called so ->put_super is too late.
502 */
503 shrink_dcache_sb(s);
504
505 dput(REISERFS_SB(s)->xattr_root);
506 REISERFS_SB(s)->xattr_root = NULL;
507 dput(REISERFS_SB(s)->priv_root);
508 REISERFS_SB(s)->priv_root = NULL;
David Howellsedc666e2006-10-11 01:22:14 -0700509 }
510
511 kill_block_super(s);
512}
513
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700514static void reiserfs_put_super(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700516 struct reiserfs_transaction_handle th;
517 th.t_trans_id = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Christoph Hellwige0ccfd92010-05-19 07:16:42 -0400519 dquot_disable(s, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
520
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +0200521 reiserfs_write_lock(s);
Christoph Hellwig6cfd0142009-05-05 15:40:36 +0200522
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700523 /* change file system state to current state if it was mounted with read-write permissions */
524 if (!(s->s_flags & MS_RDONLY)) {
525 if (!journal_begin(&th, s, 10)) {
526 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
527 1);
528 set_sb_umount_state(SB_DISK_SUPER_BLOCK(s),
529 REISERFS_SB(s)->s_mount_state);
530 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
531 }
532 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700534 /* note, journal_release checks for readonly mount, and can decide not
535 ** to do a journal_end
536 */
537 journal_release(&th, s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538
Jeff Mahoney50652272006-09-30 23:28:44 -0700539 reiserfs_free_bitmap_cache(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700541 brelse(SB_BUFFER_WITH_SB(s));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700543 print_statistics(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700545 if (REISERFS_SB(s)->reserved_blocks != 0) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400546 reiserfs_warning(s, "green-2005", "reserved blocks left %d",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700547 REISERFS_SB(s)->reserved_blocks);
548 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700550 reiserfs_proc_info_done(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +0200552 reiserfs_write_unlock(s);
553 mutex_destroy(&REISERFS_SB(s)->lock);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700554 kfree(s->s_fs_info);
555 s->s_fs_info = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556}
557
Christoph Lametere18b8902006-12-06 20:33:20 -0800558static struct kmem_cache *reiserfs_inode_cachep;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
560static struct inode *reiserfs_alloc_inode(struct super_block *sb)
561{
562 struct reiserfs_inode_info *ei;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700563 ei = (struct reiserfs_inode_info *)
Christoph Lametere94b1762006-12-06 20:33:17 -0800564 kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 if (!ei)
566 return NULL;
Al Viro0e4f6a72010-07-04 12:18:57 +0400567 atomic_set(&ei->openers, 0);
568 mutex_init(&ei->tailpack);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 return &ei->vfs_inode;
570}
571
Nick Pigginfa0d7e3d2011-01-07 17:49:49 +1100572static void reiserfs_i_callback(struct rcu_head *head)
573{
574 struct inode *inode = container_of(head, struct inode, i_rcu);
Nick Pigginfa0d7e3d2011-01-07 17:49:49 +1100575 kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
576}
577
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578static void reiserfs_destroy_inode(struct inode *inode)
579{
Nick Pigginfa0d7e3d2011-01-07 17:49:49 +1100580 call_rcu(&inode->i_rcu, reiserfs_i_callback);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581}
582
Alexey Dobriyan51cc5062008-07-25 19:45:34 -0700583static void init_once(void *foo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700585 struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Christoph Lametera35afb82007-05-16 22:10:57 -0700587 INIT_LIST_HEAD(&ei->i_prealloc_list);
588 inode_init_once(&ei->vfs_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589}
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591static int init_inodecache(void)
592{
593 reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700594 sizeof(struct
595 reiserfs_inode_info),
Paul Jacksonfffb60f2006-03-24 03:16:06 -0800596 0, (SLAB_RECLAIM_ACCOUNT|
597 SLAB_MEM_SPREAD),
Paul Mundt20c2df82007-07-20 10:11:58 +0900598 init_once);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 if (reiserfs_inode_cachep == NULL)
600 return -ENOMEM;
601 return 0;
602}
603
604static void destroy_inodecache(void)
605{
Alexey Dobriyan1a1d92c2006-09-27 01:49:40 -0700606 kmem_cache_destroy(reiserfs_inode_cachep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607}
608
609/* we don't mark inodes dirty, we just log them */
Christoph Hellwigaa385722011-05-27 06:53:02 -0400610static void reiserfs_dirty_inode(struct inode *inode, int flags)
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700611{
612 struct reiserfs_transaction_handle th;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700614 int err = 0;
Frederic Weisbeckerdc8f6d82009-04-14 05:34:25 +0200615 int lock_depth;
616
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700617 if (inode->i_sb->s_flags & MS_RDONLY) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400618 reiserfs_warning(inode->i_sb, "clm-6006",
619 "writing inode %lu on readonly FS",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700620 inode->i_ino);
621 return;
622 }
Frederic Weisbeckerdc8f6d82009-04-14 05:34:25 +0200623 lock_depth = reiserfs_write_lock_once(inode->i_sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700625 /* this is really only used for atime updates, so they don't have
626 ** to be included in O_SYNC or fsync
627 */
628 err = journal_begin(&th, inode->i_sb, 1);
Frederic Weisbeckerdc8f6d82009-04-14 05:34:25 +0200629 if (err)
630 goto out;
631
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700632 reiserfs_update_sd(&th, inode);
633 journal_end(&th, inode->i_sb, 1);
Frederic Weisbeckerdc8f6d82009-04-14 05:34:25 +0200634
635out:
636 reiserfs_write_unlock_once(inode->i_sb, lock_depth);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637}
638
Jan Karac3aa0772011-12-21 20:17:10 +0100639static int reiserfs_show_options(struct seq_file *seq, struct dentry *root)
640{
641 struct super_block *s = root->d_sb;
642 struct reiserfs_journal *journal = SB_JOURNAL(s);
643 long opts = REISERFS_SB(s)->s_mount_opt;
644
645 if (opts & (1 << REISERFS_LARGETAIL))
646 seq_puts(seq, ",tails=on");
647 else if (!(opts & (1 << REISERFS_SMALLTAIL)))
648 seq_puts(seq, ",notail");
649 /* tails=small is default so we don't show it */
650
651 if (!(opts & (1 << REISERFS_BARRIER_FLUSH)))
652 seq_puts(seq, ",barrier=none");
653 /* barrier=flush is default so we don't show it */
654
655 if (opts & (1 << REISERFS_ERROR_CONTINUE))
656 seq_puts(seq, ",errors=continue");
657 else if (opts & (1 << REISERFS_ERROR_PANIC))
658 seq_puts(seq, ",errors=panic");
659 /* errors=ro is default so we don't show it */
660
661 if (opts & (1 << REISERFS_DATA_LOG))
662 seq_puts(seq, ",data=journal");
663 else if (opts & (1 << REISERFS_DATA_WRITEBACK))
664 seq_puts(seq, ",data=writeback");
665 /* data=ordered is default so we don't show it */
666
667 if (opts & (1 << REISERFS_ATTRS))
668 seq_puts(seq, ",attrs");
669
670 if (opts & (1 << REISERFS_XATTRS_USER))
671 seq_puts(seq, ",user_xattr");
672
673 if (opts & (1 << REISERFS_EXPOSE_PRIVROOT))
674 seq_puts(seq, ",expose_privroot");
675
676 if (opts & (1 << REISERFS_POSIXACL))
677 seq_puts(seq, ",acl");
678
679 if (REISERFS_SB(s)->s_jdev)
680 seq_printf(seq, ",jdev=%s", REISERFS_SB(s)->s_jdev);
681
682 if (journal->j_max_commit_age != journal->j_default_max_commit_age)
683 seq_printf(seq, ",commit=%d", journal->j_max_commit_age);
684
685#ifdef CONFIG_QUOTA
686 if (REISERFS_SB(s)->s_qf_names[USRQUOTA])
687 seq_printf(seq, ",usrjquota=%s", REISERFS_SB(s)->s_qf_names[USRQUOTA]);
688 else if (opts & (1 << REISERFS_USRQUOTA))
689 seq_puts(seq, ",usrquota");
690 if (REISERFS_SB(s)->s_qf_names[GRPQUOTA])
691 seq_printf(seq, ",grpjquota=%s", REISERFS_SB(s)->s_qf_names[GRPQUOTA]);
692 else if (opts & (1 << REISERFS_GRPQUOTA))
693 seq_puts(seq, ",grpquota");
694 if (REISERFS_SB(s)->s_jquota_fmt) {
695 if (REISERFS_SB(s)->s_jquota_fmt == QFMT_VFS_OLD)
696 seq_puts(seq, ",jqfmt=vfsold");
697 else if (REISERFS_SB(s)->s_jquota_fmt == QFMT_VFS_V0)
698 seq_puts(seq, ",jqfmt=vfsv0");
699 }
700#endif
701
702 /* Block allocator options */
703 if (opts & (1 << REISERFS_NO_BORDER))
704 seq_puts(seq, ",block-allocator=noborder");
705 if (opts & (1 << REISERFS_NO_UNHASHED_RELOCATION))
706 seq_puts(seq, ",block-allocator=no_unhashed_relocation");
707 if (opts & (1 << REISERFS_HASHED_RELOCATION))
708 seq_puts(seq, ",block-allocator=hashed_relocation");
709 if (opts & (1 << REISERFS_TEST4))
710 seq_puts(seq, ",block-allocator=test4");
711 show_alloc_options(seq, s);
712 return 0;
713}
714
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700716static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
717 size_t, loff_t);
718static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t,
719 loff_t);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720#endif
721
Josef 'Jeff' Sipekee9b6d62007-02-12 00:55:41 -0800722static const struct super_operations reiserfs_sops = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700723 .alloc_inode = reiserfs_alloc_inode,
724 .destroy_inode = reiserfs_destroy_inode,
725 .write_inode = reiserfs_write_inode,
726 .dirty_inode = reiserfs_dirty_inode,
Al Viro845a2cc2010-06-07 11:37:37 -0400727 .evict_inode = reiserfs_evict_inode,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700728 .put_super = reiserfs_put_super,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700729 .sync_fs = reiserfs_sync_fs,
Takashi Satoc4be0c12009-01-09 16:40:58 -0800730 .freeze_fs = reiserfs_freeze,
731 .unfreeze_fs = reiserfs_unfreeze,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700732 .statfs = reiserfs_statfs,
733 .remount_fs = reiserfs_remount,
Jan Karac3aa0772011-12-21 20:17:10 +0100734 .show_options = reiserfs_show_options,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700736 .quota_read = reiserfs_quota_read,
737 .quota_write = reiserfs_quota_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738#endif
739};
740
741#ifdef CONFIG_QUOTA
742#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
743
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744static int reiserfs_write_dquot(struct dquot *);
745static int reiserfs_acquire_dquot(struct dquot *);
746static int reiserfs_release_dquot(struct dquot *);
747static int reiserfs_mark_dquot_dirty(struct dquot *);
748static int reiserfs_write_info(struct super_block *, int);
Jan Karaf00c9e42010-09-15 17:38:58 +0200749static int reiserfs_quota_on(struct super_block *, int, int, struct path *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
Alexey Dobriyan61e225d2009-09-21 17:01:08 -0700751static const struct dquot_operations reiserfs_quota_operations = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700752 .write_dquot = reiserfs_write_dquot,
753 .acquire_dquot = reiserfs_acquire_dquot,
754 .release_dquot = reiserfs_release_dquot,
755 .mark_dirty = reiserfs_mark_dquot_dirty,
756 .write_info = reiserfs_write_info,
Jan Kara41030032008-11-25 15:31:33 +0100757 .alloc_dquot = dquot_alloc,
758 .destroy_dquot = dquot_destroy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759};
760
Alexey Dobriyan0d54b212009-09-21 17:01:09 -0700761static const struct quotactl_ops reiserfs_qctl_operations = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700762 .quota_on = reiserfs_quota_on,
Christoph Hellwig287a8092010-05-19 07:16:45 -0400763 .quota_off = dquot_quota_off,
764 .quota_sync = dquot_quota_sync,
765 .get_info = dquot_get_dqinfo,
766 .set_info = dquot_set_dqinfo,
767 .get_dqblk = dquot_get_dqblk,
768 .set_dqblk = dquot_set_dqblk,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769};
770#endif
771
Christoph Hellwig39655162007-10-21 16:42:17 -0700772static const struct export_operations reiserfs_export_ops = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700773 .encode_fh = reiserfs_encode_fh,
Christoph Hellwigbe55caf2007-10-21 16:42:13 -0700774 .fh_to_dentry = reiserfs_fh_to_dentry,
775 .fh_to_parent = reiserfs_fh_to_parent,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700776 .get_parent = reiserfs_get_parent,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700777};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
779/* this struct is used in reiserfs_getopt () for containing the value for those
780 mount options that have values rather than being toggles. */
781typedef struct {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700782 char *value;
783 int setmask; /* bitmask which is to set on mount_options bitmask when this
784 value is found, 0 is no bits are to be changed. */
785 int clrmask; /* bitmask which is to clear on mount_options bitmask when this
786 value is found, 0 is no bits are to be changed. This is
787 applied BEFORE setmask */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788} arg_desc_t;
789
790/* Set this bit in arg_required to allow empty arguments */
791#define REISERFS_OPT_ALLOWEMPTY 31
792
793/* this struct is used in reiserfs_getopt() for describing the set of reiserfs
794 mount options */
795typedef struct {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700796 char *option_name;
797 int arg_required; /* 0 if argument is not required, not 0 otherwise */
798 const arg_desc_t *values; /* list of values accepted by an option */
799 int setmask; /* bitmask which is to set on mount_options bitmask when this
800 value is found, 0 is no bits are to be changed. */
801 int clrmask; /* bitmask which is to clear on mount_options bitmask when this
802 value is found, 0 is no bits are to be changed. This is
803 applied BEFORE setmask */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804} opt_desc_t;
805
806/* possible values for -o data= */
807static const arg_desc_t logging_mode[] = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700808 {"ordered", 1 << REISERFS_DATA_ORDERED,
809 (1 << REISERFS_DATA_LOG | 1 << REISERFS_DATA_WRITEBACK)},
810 {"journal", 1 << REISERFS_DATA_LOG,
811 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_WRITEBACK)},
812 {"writeback", 1 << REISERFS_DATA_WRITEBACK,
813 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_LOG)},
Vladimir V. Savelievcd02b962006-03-25 03:07:15 -0800814 {.value = NULL}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815};
816
817/* possible values for -o barrier= */
818static const arg_desc_t barrier_mode[] = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700819 {"none", 1 << REISERFS_BARRIER_NONE, 1 << REISERFS_BARRIER_FLUSH},
820 {"flush", 1 << REISERFS_BARRIER_FLUSH, 1 << REISERFS_BARRIER_NONE},
Vladimir V. Savelievcd02b962006-03-25 03:07:15 -0800821 {.value = NULL}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822};
823
824/* possible values for "-o block-allocator=" and bits which are to be set in
825 s_mount_opt of reiserfs specific part of in-core super block */
826static const arg_desc_t balloc[] = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700827 {"noborder", 1 << REISERFS_NO_BORDER, 0},
828 {"border", 0, 1 << REISERFS_NO_BORDER},
829 {"no_unhashed_relocation", 1 << REISERFS_NO_UNHASHED_RELOCATION, 0},
830 {"hashed_relocation", 1 << REISERFS_HASHED_RELOCATION, 0},
831 {"test4", 1 << REISERFS_TEST4, 0},
832 {"notest4", 0, 1 << REISERFS_TEST4},
833 {NULL, 0, 0}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834};
835
836static const arg_desc_t tails[] = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700837 {"on", 1 << REISERFS_LARGETAIL, 1 << REISERFS_SMALLTAIL},
838 {"off", 0, (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},
839 {"small", 1 << REISERFS_SMALLTAIL, 1 << REISERFS_LARGETAIL},
840 {NULL, 0, 0}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841};
842
843static const arg_desc_t error_actions[] = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700844 {"panic", 1 << REISERFS_ERROR_PANIC,
845 (1 << REISERFS_ERROR_RO | 1 << REISERFS_ERROR_CONTINUE)},
846 {"ro-remount", 1 << REISERFS_ERROR_RO,
847 (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_CONTINUE)},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848#ifdef REISERFS_JOURNAL_ERROR_ALLOWS_NO_LOG
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700849 {"continue", 1 << REISERFS_ERROR_CONTINUE,
850 (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_RO)},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851#endif
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700852 {NULL, 0, 0},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853};
854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855/* proceed only one option from a list *cur - string containing of mount options
856 opts - array of options which are accepted
857 opt_arg - if option is found and requires an argument and if it is specifed
858 in the input - pointer to the argument is stored here
859 bit_flags - if option requires to set a certain bit - it is set here
860 return -1 if unknown option is found, opt->arg_required otherwise */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700861static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
862 char **opt_arg, unsigned long *bit_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700864 char *p;
Jeff Mahoney0222e652009-03-30 14:02:44 -0400865 /* foo=bar,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700866 ^ ^ ^
867 | | +-- option_end
868 | +-- arg_start
869 +-- option_start
870 */
871 const opt_desc_t *opt;
872 const arg_desc_t *arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700874 p = *cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700876 /* assume argument cannot contain commas */
877 *cur = strchr(p, ',');
878 if (*cur) {
879 *(*cur) = '\0';
880 (*cur)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700883 if (!strncmp(p, "alloc=", 6)) {
884 /* Ugly special case, probably we should redo options parser so that
885 it can understand several arguments for some options, also so that
886 it can fill several bitfields with option values. */
887 if (reiserfs_parse_alloc_options(s, p + 6)) {
888 return -1;
889 } else {
890 return 0;
891 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700893
894 /* for every option in the list */
895 for (opt = opts; opt->option_name; opt++) {
896 if (!strncmp(p, opt->option_name, strlen(opt->option_name))) {
897 if (bit_flags) {
898 if (opt->clrmask ==
899 (1 << REISERFS_UNSUPPORTED_OPT))
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400900 reiserfs_warning(s, "super-6500",
901 "%s not supported.\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700902 p);
903 else
904 *bit_flags &= ~opt->clrmask;
905 if (opt->setmask ==
906 (1 << REISERFS_UNSUPPORTED_OPT))
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400907 reiserfs_warning(s, "super-6501",
908 "%s not supported.\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700909 p);
910 else
911 *bit_flags |= opt->setmask;
912 }
913 break;
914 }
915 }
916 if (!opt->option_name) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400917 reiserfs_warning(s, "super-6502",
918 "unknown mount option \"%s\"", p);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700919 return -1;
920 }
921
922 p += strlen(opt->option_name);
923 switch (*p) {
924 case '=':
925 if (!opt->arg_required) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400926 reiserfs_warning(s, "super-6503",
927 "the option \"%s\" does not "
928 "require an argument\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700929 opt->option_name);
930 return -1;
931 }
932 break;
933
934 case 0:
935 if (opt->arg_required) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400936 reiserfs_warning(s, "super-6504",
937 "the option \"%s\" requires an "
938 "argument\n", opt->option_name);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700939 return -1;
940 }
941 break;
942 default:
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400943 reiserfs_warning(s, "super-6505",
944 "head of option \"%s\" is only correct\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700945 opt->option_name);
946 return -1;
947 }
948
949 /* move to the argument, or to next option if argument is not required */
950 p++;
951
952 if (opt->arg_required
953 && !(opt->arg_required & (1 << REISERFS_OPT_ALLOWEMPTY))
954 && !strlen(p)) {
955 /* this catches "option=," if not allowed */
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400956 reiserfs_warning(s, "super-6506",
957 "empty argument for \"%s\"\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700958 opt->option_name);
959 return -1;
960 }
961
962 if (!opt->values) {
963 /* *=NULLopt_arg contains pointer to argument */
964 *opt_arg = p;
965 return opt->arg_required & ~(1 << REISERFS_OPT_ALLOWEMPTY);
966 }
967
968 /* values possible for this option are listed in opt->values */
969 for (arg = opt->values; arg->value; arg++) {
970 if (!strcmp(p, arg->value)) {
971 if (bit_flags) {
972 *bit_flags &= ~arg->clrmask;
973 *bit_flags |= arg->setmask;
974 }
975 return opt->arg_required;
976 }
977 }
978
Jeff Mahoney45b03d52009-03-30 14:02:21 -0400979 reiserfs_warning(s, "super-6506",
980 "bad value \"%s\" for option \"%s\"\n", p,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700981 opt->option_name);
982 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983}
984
985/* returns 0 if something is wrong in option string, 1 - otherwise */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700986static int reiserfs_parse_options(struct super_block *s, char *options, /* string given via mount's -o */
987 unsigned long *mount_options,
988 /* after the parsing phase, contains the
989 collection of bitflags defining what
990 mount options were selected. */
991 unsigned long *blocks, /* strtol-ed from NNN of resize=NNN */
992 char **jdev_name,
Jan Kara00b44192008-07-25 01:46:38 -0700993 unsigned int *commit_max_age,
994 char **qf_names,
995 unsigned int *qfmt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -0700997 int c;
998 char *arg = NULL;
999 char *pos;
1000 opt_desc_t opts[] = {
1001 /* Compatibility stuff, so that -o notail for old setups still work */
1002 {"tails",.arg_required = 't',.values = tails},
1003 {"notail",.clrmask =
1004 (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},
1005 {"conv",.setmask = 1 << REISERFS_CONVERT},
1006 {"attrs",.setmask = 1 << REISERFS_ATTRS},
1007 {"noattrs",.clrmask = 1 << REISERFS_ATTRS},
Jeff Mahoney73422812009-05-10 16:05:39 -04001008 {"expose_privroot", .setmask = 1 << REISERFS_EXPOSE_PRIVROOT},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009#ifdef CONFIG_REISERFS_FS_XATTR
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001010 {"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},
1011 {"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012#else
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001013 {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
1014 {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015#endif
1016#ifdef CONFIG_REISERFS_FS_POSIX_ACL
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001017 {"acl",.setmask = 1 << REISERFS_POSIXACL},
1018 {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019#else
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001020 {"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
1021 {"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022#endif
Vladimir V. Savelievcd02b962006-03-25 03:07:15 -08001023 {.option_name = "nolog"},
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001024 {"replayonly",.setmask = 1 << REPLAYONLY},
1025 {"block-allocator",.arg_required = 'a',.values = balloc},
1026 {"data",.arg_required = 'd',.values = logging_mode},
1027 {"barrier",.arg_required = 'b',.values = barrier_mode},
1028 {"resize",.arg_required = 'r',.values = NULL},
1029 {"jdev",.arg_required = 'j',.values = NULL},
1030 {"nolargeio",.arg_required = 'w',.values = NULL},
1031 {"commit",.arg_required = 'c',.values = NULL},
Jan Karac3aa0772011-12-21 20:17:10 +01001032 {"usrquota",.setmask = 1 << REISERFS_USRQUOTA},
1033 {"grpquota",.setmask = 1 << REISERFS_GRPQUOTA},
1034 {"noquota",.clrmask = 1 << REISERFS_USRQUOTA | 1 << REISERFS_GRPQUOTA},
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001035 {"errors",.arg_required = 'e',.values = error_actions},
1036 {"usrjquota",.arg_required =
1037 'u' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
1038 {"grpjquota",.arg_required =
1039 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
1040 {"jqfmt",.arg_required = 'f',.values = NULL},
Vladimir V. Savelievcd02b962006-03-25 03:07:15 -08001041 {.option_name = NULL}
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001042 };
1043
1044 *blocks = 0;
1045 if (!options || !*options)
1046 /* use default configuration: create tails, journaling on, no
1047 conversion to newest format */
1048 return 1;
1049
1050 for (pos = options; pos;) {
1051 c = reiserfs_getopt(s, &pos, opts, &arg, mount_options);
1052 if (c == -1)
1053 /* wrong option is given */
1054 return 0;
1055
1056 if (c == 'r') {
1057 char *p;
1058
1059 p = NULL;
1060 /* "resize=NNN" or "resize=auto" */
1061
1062 if (!strcmp(arg, "auto")) {
1063 /* From JFS code, to auto-get the size. */
1064 *blocks =
1065 s->s_bdev->bd_inode->i_size >> s->
1066 s_blocksize_bits;
1067 } else {
1068 *blocks = simple_strtoul(arg, &p, 0);
1069 if (*p != '\0') {
1070 /* NNN does not look like a number */
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001071 reiserfs_warning(s, "super-6507",
1072 "bad value %s for "
1073 "-oresize\n", arg);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001074 return 0;
1075 }
1076 }
1077 }
1078
1079 if (c == 'c') {
1080 char *p = NULL;
1081 unsigned long val = simple_strtoul(arg, &p, 0);
1082 /* commit=NNN (time in seconds) */
1083 if (*p != '\0' || val >= (unsigned int)-1) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001084 reiserfs_warning(s, "super-6508",
1085 "bad value %s for -ocommit\n",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001086 arg);
1087 return 0;
1088 }
1089 *commit_max_age = (unsigned int)val;
1090 }
1091
1092 if (c == 'w') {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001093 reiserfs_warning(s, "super-6509", "nolargeio option "
1094 "is no longer supported");
Adrian Bunk36b756f2006-09-27 01:50:50 -07001095 return 0;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001096 }
1097
1098 if (c == 'j') {
1099 if (arg && *arg && jdev_name) {
1100 if (*jdev_name) { //Hm, already assigned?
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001101 reiserfs_warning(s, "super-6510",
1102 "journal device was "
1103 "already specified to "
1104 "be %s", *jdev_name);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001105 return 0;
1106 }
1107 *jdev_name = arg;
1108 }
1109 }
1110#ifdef CONFIG_QUOTA
1111 if (c == 'u' || c == 'g') {
1112 int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
1113
Jan Kara6929f892008-08-20 18:16:36 +02001114 if (sb_any_quota_loaded(s) &&
Jan Kara00b44192008-07-25 01:46:38 -07001115 (!*arg != !REISERFS_SB(s)->s_qf_names[qtype])) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001116 reiserfs_warning(s, "super-6511",
1117 "cannot change journaled "
1118 "quota options when quota "
1119 "turned on.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001120 return 0;
1121 }
1122 if (*arg) { /* Some filename specified? */
1123 if (REISERFS_SB(s)->s_qf_names[qtype]
1124 && strcmp(REISERFS_SB(s)->s_qf_names[qtype],
1125 arg)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001126 reiserfs_warning(s, "super-6512",
1127 "%s quota file "
1128 "already specified.",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001129 QTYPE2NAME(qtype));
1130 return 0;
1131 }
1132 if (strchr(arg, '/')) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001133 reiserfs_warning(s, "super-6513",
1134 "quotafile must be "
1135 "on filesystem root.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001136 return 0;
1137 }
Jan Kara00b44192008-07-25 01:46:38 -07001138 qf_names[qtype] =
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001139 kmalloc(strlen(arg) + 1, GFP_KERNEL);
Jan Kara00b44192008-07-25 01:46:38 -07001140 if (!qf_names[qtype]) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001141 reiserfs_warning(s, "reiserfs-2502",
1142 "not enough memory "
1143 "for storing "
1144 "quotafile name.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001145 return 0;
1146 }
Jan Kara00b44192008-07-25 01:46:38 -07001147 strcpy(qf_names[qtype], arg);
Jan Karac3aa0772011-12-21 20:17:10 +01001148 if (qtype == USRQUOTA)
1149 *mount_options |= 1 << REISERFS_USRQUOTA;
1150 else
1151 *mount_options |= 1 << REISERFS_GRPQUOTA;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001152 } else {
Jan Kara00b44192008-07-25 01:46:38 -07001153 if (qf_names[qtype] !=
1154 REISERFS_SB(s)->s_qf_names[qtype])
1155 kfree(qf_names[qtype]);
1156 qf_names[qtype] = NULL;
Jan Karac3aa0772011-12-21 20:17:10 +01001157 if (qtype == USRQUOTA)
1158 *mount_options &= ~(1 << REISERFS_USRQUOTA);
1159 else
1160 *mount_options &= ~(1 << REISERFS_GRPQUOTA);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001161 }
1162 }
1163 if (c == 'f') {
1164 if (!strcmp(arg, "vfsold"))
Jan Kara00b44192008-07-25 01:46:38 -07001165 *qfmt = QFMT_VFS_OLD;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001166 else if (!strcmp(arg, "vfsv0"))
Jan Kara00b44192008-07-25 01:46:38 -07001167 *qfmt = QFMT_VFS_V0;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001168 else {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001169 reiserfs_warning(s, "super-6514",
1170 "unknown quota format "
1171 "specified.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001172 return 0;
1173 }
Jan Kara6929f892008-08-20 18:16:36 +02001174 if (sb_any_quota_loaded(s) &&
Jan Kara00b44192008-07-25 01:46:38 -07001175 *qfmt != REISERFS_SB(s)->s_jquota_fmt) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001176 reiserfs_warning(s, "super-6515",
1177 "cannot change journaled "
1178 "quota options when quota "
1179 "turned on.");
Jan Kara00b44192008-07-25 01:46:38 -07001180 return 0;
1181 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001182 }
1183#else
1184 if (c == 'u' || c == 'g' || c == 'f') {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001185 reiserfs_warning(s, "reiserfs-2503", "journaled "
1186 "quota options not supported.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001187 return 0;
1188 }
1189#endif
1190 }
1191
1192#ifdef CONFIG_QUOTA
Jan Kara00b44192008-07-25 01:46:38 -07001193 if (!REISERFS_SB(s)->s_jquota_fmt && !*qfmt
1194 && (qf_names[USRQUOTA] || qf_names[GRPQUOTA])) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001195 reiserfs_warning(s, "super-6515",
1196 "journaled quota format not specified.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001197 return 0;
1198 }
Jan Karac3aa0772011-12-21 20:17:10 +01001199 if ((!(*mount_options & (1 << REISERFS_USRQUOTA)) &&
1200 sb_has_quota_loaded(s, USRQUOTA)) ||
1201 (!(*mount_options & (1 << REISERFS_GRPQUOTA)) &&
1202 sb_has_quota_loaded(s, GRPQUOTA))) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001203 reiserfs_warning(s, "super-6516", "quota options must "
1204 "be present when quota is turned on.");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001205 return 0;
1206 }
1207#endif
1208
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210}
1211
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001212static void switch_data_mode(struct super_block *s, unsigned long mode)
1213{
1214 REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |
1215 (1 << REISERFS_DATA_ORDERED) |
1216 (1 << REISERFS_DATA_WRITEBACK));
1217 REISERFS_SB(s)->s_mount_opt |= (1 << mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218}
1219
1220static void handle_data_mode(struct super_block *s, unsigned long mount_options)
1221{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001222 if (mount_options & (1 << REISERFS_DATA_LOG)) {
1223 if (!reiserfs_data_log(s)) {
1224 switch_data_mode(s, REISERFS_DATA_LOG);
1225 reiserfs_info(s, "switching to journaled data mode\n");
1226 }
1227 } else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {
1228 if (!reiserfs_data_ordered(s)) {
1229 switch_data_mode(s, REISERFS_DATA_ORDERED);
1230 reiserfs_info(s, "switching to ordered data mode\n");
1231 }
1232 } else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {
1233 if (!reiserfs_data_writeback(s)) {
1234 switch_data_mode(s, REISERFS_DATA_WRITEBACK);
1235 reiserfs_info(s, "switching to writeback data mode\n");
1236 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238}
1239
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001240static void handle_barrier_mode(struct super_block *s, unsigned long bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001242 int flush = (1 << REISERFS_BARRIER_FLUSH);
1243 int none = (1 << REISERFS_BARRIER_NONE);
1244 int all_barrier = flush | none;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001246 if (bits & all_barrier) {
1247 REISERFS_SB(s)->s_mount_opt &= ~all_barrier;
1248 if (bits & flush) {
1249 REISERFS_SB(s)->s_mount_opt |= flush;
1250 printk("reiserfs: enabling write barrier flush mode\n");
1251 } else if (bits & none) {
1252 REISERFS_SB(s)->s_mount_opt |= none;
1253 printk("reiserfs: write barriers turned off\n");
1254 }
1255 }
1256}
1257
1258static void handle_attrs(struct super_block *s)
1259{
1260 struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
1261
1262 if (reiserfs_attrs(s)) {
1263 if (old_format_only(s)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001264 reiserfs_warning(s, "super-6517", "cannot support "
1265 "attributes on 3.5.x disk format");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001266 REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 return;
1268 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001269 if (!(le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001270 reiserfs_warning(s, "super-6518", "cannot support "
1271 "attributes until flag is set in "
1272 "super-block");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001273 REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 }
1275 }
1276}
1277
Jan Kara00b44192008-07-25 01:46:38 -07001278#ifdef CONFIG_QUOTA
1279static void handle_quota_files(struct super_block *s, char **qf_names,
1280 unsigned int *qfmt)
1281{
1282 int i;
1283
1284 for (i = 0; i < MAXQUOTAS; i++) {
1285 if (qf_names[i] != REISERFS_SB(s)->s_qf_names[i])
1286 kfree(REISERFS_SB(s)->s_qf_names[i]);
1287 REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
1288 }
Jan Karaa06d7892011-12-21 17:35:34 +01001289 if (*qfmt)
1290 REISERFS_SB(s)->s_jquota_fmt = *qfmt;
Jan Kara00b44192008-07-25 01:46:38 -07001291}
1292#endif
1293
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001294static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001296 struct reiserfs_super_block *rs;
1297 struct reiserfs_transaction_handle th;
1298 unsigned long blocks;
1299 unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
1300 unsigned long safe_mask = 0;
1301 unsigned int commit_max_age = (unsigned int)-1;
1302 struct reiserfs_journal *journal = SB_JOURNAL(s);
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001303 char *new_opts = kstrdup(arg, GFP_KERNEL);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001304 int err;
Jan Kara00b44192008-07-25 01:46:38 -07001305 char *qf_names[MAXQUOTAS];
1306 unsigned int qfmt = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001308 int i;
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02001309#endif
Jan Kara00b44192008-07-25 01:46:38 -07001310
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02001311 reiserfs_write_lock(s);
1312
1313#ifdef CONFIG_QUOTA
Jan Kara00b44192008-07-25 01:46:38 -07001314 memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315#endif
1316
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001317 rs = SB_DISK_SUPER_BLOCK(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001319 if (!reiserfs_parse_options
Jan Kara00b44192008-07-25 01:46:38 -07001320 (s, arg, &mount_options, &blocks, NULL, &commit_max_age,
1321 qf_names, &qfmt)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322#ifdef CONFIG_QUOTA
Jan Kara00b44192008-07-25 01:46:38 -07001323 for (i = 0; i < MAXQUOTAS; i++)
1324 if (qf_names[i] != REISERFS_SB(s)->s_qf_names[i])
1325 kfree(qf_names[i]);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001326#endif
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001327 err = -EINVAL;
1328 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 }
Jan Kara00b44192008-07-25 01:46:38 -07001330#ifdef CONFIG_QUOTA
1331 handle_quota_files(s, qf_names, &qfmt);
1332#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001334 handle_attrs(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001336 /* Add options that are safe here */
1337 safe_mask |= 1 << REISERFS_SMALLTAIL;
1338 safe_mask |= 1 << REISERFS_LARGETAIL;
1339 safe_mask |= 1 << REISERFS_NO_BORDER;
1340 safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
1341 safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
1342 safe_mask |= 1 << REISERFS_TEST4;
1343 safe_mask |= 1 << REISERFS_ATTRS;
1344 safe_mask |= 1 << REISERFS_XATTRS_USER;
1345 safe_mask |= 1 << REISERFS_POSIXACL;
1346 safe_mask |= 1 << REISERFS_BARRIER_FLUSH;
1347 safe_mask |= 1 << REISERFS_BARRIER_NONE;
1348 safe_mask |= 1 << REISERFS_ERROR_RO;
1349 safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
1350 safe_mask |= 1 << REISERFS_ERROR_PANIC;
Jan Karac3aa0772011-12-21 20:17:10 +01001351 safe_mask |= 1 << REISERFS_USRQUOTA;
1352 safe_mask |= 1 << REISERFS_GRPQUOTA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001354 /* Update the bitmask, taking care to keep
1355 * the bits we're not allowed to change here */
1356 REISERFS_SB(s)->s_mount_opt =
1357 (REISERFS_SB(s)->
1358 s_mount_opt & ~safe_mask) | (mount_options & safe_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001360 if (commit_max_age != 0 && commit_max_age != (unsigned int)-1) {
1361 journal->j_max_commit_age = commit_max_age;
1362 journal->j_max_trans_age = commit_max_age;
1363 } else if (commit_max_age == 0) {
1364 /* 0 means restore defaults. */
1365 journal->j_max_commit_age = journal->j_default_max_commit_age;
1366 journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
1367 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001369 if (blocks) {
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001370 err = reiserfs_resize(s, blocks);
1371 if (err != 0)
1372 goto out_err;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001373 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001375 if (*mount_flags & MS_RDONLY) {
1376 reiserfs_xattr_init(s, *mount_flags);
1377 /* remount read-only */
1378 if (s->s_flags & MS_RDONLY)
1379 /* it is read-only already */
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001380 goto out_ok;
Christoph Hellwigc79d9672010-05-19 07:16:40 -04001381
Christoph Hellwig0f0dd622010-05-19 07:16:41 -04001382 err = dquot_suspend(s, -1);
1383 if (err < 0)
Christoph Hellwigc79d9672010-05-19 07:16:40 -04001384 goto out_err;
Christoph Hellwigc79d9672010-05-19 07:16:40 -04001385
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001386 /* try to remount file system with read-only permissions */
1387 if (sb_umount_state(rs) == REISERFS_VALID_FS
1388 || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001389 goto out_ok;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001390 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001392 err = journal_begin(&th, s, 10);
1393 if (err)
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001394 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001396 /* Mounting a rw partition read-only. */
1397 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
1398 set_sb_umount_state(rs, REISERFS_SB(s)->s_mount_state);
1399 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
1400 } else {
1401 /* remount read-write */
1402 if (!(s->s_flags & MS_RDONLY)) {
1403 reiserfs_xattr_init(s, *mount_flags);
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001404 goto out_ok; /* We are read-write already */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001407 if (reiserfs_is_journal_aborted(journal)) {
1408 err = journal->j_errno;
1409 goto out_err;
1410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001412 handle_data_mode(s, mount_options);
1413 handle_barrier_mode(s, mount_options);
1414 REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
1415 s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
1416 err = journal_begin(&th, s, 10);
1417 if (err)
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001418 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001420 /* Mount a partition which is read-only, read-write */
1421 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
1422 REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
1423 s->s_flags &= ~MS_RDONLY;
1424 set_sb_umount_state(rs, REISERFS_ERROR_FS);
Jeff Mahoney702d21c2009-03-30 14:02:16 -04001425 if (!old_format_only(s))
1426 set_sb_mnt_count(rs, sb_mnt_count(rs) + 1);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001427 /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
1428 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
1429 REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS;
1430 }
1431 /* this will force a full flush of all journal lists */
1432 SB_JOURNAL(s)->j_must_wait = 1;
1433 err = journal_end(&th, s, 10);
1434 if (err)
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001435 goto out_err;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001436
1437 if (!(*mount_flags & MS_RDONLY)) {
Christoph Hellwig0f0dd622010-05-19 07:16:41 -04001438 dquot_resume(s, -1);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001439 finish_unfinished(s);
1440 reiserfs_xattr_init(s, *mount_flags);
1441 }
1442
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001443out_ok:
Al Viro2a32ceb2009-05-08 16:05:57 -04001444 replace_mount_options(s, new_opts);
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02001445 reiserfs_write_unlock(s);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001446 return 0;
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001447
1448out_err:
1449 kfree(new_opts);
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02001450 reiserfs_write_unlock(s);
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001451 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452}
1453
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001454static int read_super_block(struct super_block *s, int offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001456 struct buffer_head *bh;
1457 struct reiserfs_super_block *rs;
1458 int fs_blocksize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001460 bh = sb_bread(s, offset / s->s_blocksize);
1461 if (!bh) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001462 reiserfs_warning(s, "sh-2006",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001463 "bread failed (dev %s, block %lu, size %lu)",
1464 reiserfs_bdevname(s), offset / s->s_blocksize,
1465 s->s_blocksize);
1466 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001469 rs = (struct reiserfs_super_block *)bh->b_data;
1470 if (!is_any_reiserfs_magic_string(rs)) {
1471 brelse(bh);
1472 return 1;
1473 }
1474 //
1475 // ok, reiserfs signature (old or new) found in at the given offset
Jeff Mahoney0222e652009-03-30 14:02:44 -04001476 //
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001477 fs_blocksize = sb_blocksize(rs);
1478 brelse(bh);
1479 sb_set_blocksize(s, fs_blocksize);
1480
1481 bh = sb_bread(s, offset / s->s_blocksize);
1482 if (!bh) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001483 reiserfs_warning(s, "sh-2007",
1484 "bread failed (dev %s, block %lu, size %lu)",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001485 reiserfs_bdevname(s), offset / s->s_blocksize,
1486 s->s_blocksize);
1487 return 1;
1488 }
1489
1490 rs = (struct reiserfs_super_block *)bh->b_data;
1491 if (sb_blocksize(rs) != s->s_blocksize) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001492 reiserfs_warning(s, "sh-2011", "can't find a reiserfs "
1493 "filesystem on (dev %s, block %Lu, size %lu)",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001494 reiserfs_bdevname(s),
1495 (unsigned long long)bh->b_blocknr,
1496 s->s_blocksize);
1497 brelse(bh);
1498 return 1;
1499 }
1500
1501 if (rs->s_v1.s_root_block == cpu_to_le32(-1)) {
1502 brelse(bh);
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001503 reiserfs_warning(s, "super-6519", "Unfinished reiserfsck "
1504 "--rebuild-tree run detected. Please run\n"
1505 "reiserfsck --rebuild-tree and wait for a "
1506 "completion. If that fails\n"
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001507 "get newer reiserfsprogs package");
1508 return 1;
1509 }
1510
1511 SB_BUFFER_WITH_SB(s) = bh;
1512 SB_DISK_SUPER_BLOCK(s) = rs;
1513
1514 if (is_reiserfs_jr(rs)) {
1515 /* magic is of non-standard journal filesystem, look at s_version to
1516 find which format is in use */
1517 if (sb_version(rs) == REISERFS_VERSION_2)
Jeff Mahoney1d889d92009-03-30 14:02:20 -04001518 reiserfs_info(s, "found reiserfs format \"3.6\""
1519 " with non-standard journal\n");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001520 else if (sb_version(rs) == REISERFS_VERSION_1)
Jeff Mahoney1d889d92009-03-30 14:02:20 -04001521 reiserfs_info(s, "found reiserfs format \"3.5\""
1522 " with non-standard journal\n");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001523 else {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001524 reiserfs_warning(s, "sh-2012", "found unknown "
1525 "format \"%u\" of reiserfs with "
1526 "non-standard magic", sb_version(rs));
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001527 return 1;
1528 }
1529 } else
1530 /* s_version of standard format may contain incorrect information,
1531 so we just look at the magic string */
1532 reiserfs_info(s,
1533 "found reiserfs format \"%s\" with standard journal\n",
1534 is_reiserfs_3_5(rs) ? "3.5" : "3.6");
1535
1536 s->s_op = &reiserfs_sops;
1537 s->s_export_op = &reiserfs_export_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538#ifdef CONFIG_QUOTA
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001539 s->s_qcop = &reiserfs_qctl_operations;
1540 s->dq_op = &reiserfs_quota_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541#endif
1542
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001543 /* new format is limited by the 32 bit wide i_blocks field, want to
1544 ** be one full block below that.
1545 */
1546 s->s_maxbytes = (512LL << 32) - s->s_blocksize;
1547 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548}
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550/* after journal replay, reread all bitmap and super blocks */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001551static int reread_meta_blocks(struct super_block *s)
1552{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001553 ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
1554 wait_on_buffer(SB_BUFFER_WITH_SB(s));
1555 if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001556 reiserfs_warning(s, "reiserfs-2504", "error reading the super");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001557 return 1;
1558 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001560 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561}
1562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563/////////////////////////////////////////////////////
1564// hash detection stuff
1565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566// if root directory is empty - we set default - Yura's - hash and
1567// warn about it
1568// FIXME: we look for only one name in a directory. If tea and yura
1569// bith have the same value - we ask user to send report to the
1570// mailing list
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001571static __u32 find_hash_out(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001573 int retval;
1574 struct inode *inode;
1575 struct cpu_key key;
1576 INITIALIZE_PATH(path);
1577 struct reiserfs_dir_entry de;
1578 __u32 hash = DEFAULT_HASH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001580 inode = s->s_root->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001582 do { // Some serious "goto"-hater was there ;)
1583 u32 teahash, r5hash, yurahash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001585 make_cpu_key(&key, inode, ~0, TYPE_DIRENTRY, 3);
1586 retval = search_by_entry_key(s, &key, &path, &de);
1587 if (retval == IO_ERROR) {
1588 pathrelse(&path);
1589 return UNSET_HASH;
1590 }
1591 if (retval == NAME_NOT_FOUND)
1592 de.de_entry_num--;
1593 set_de_name_and_namelen(&de);
1594 if (deh_offset(&(de.de_deh[de.de_entry_num])) == DOT_DOT_OFFSET) {
1595 /* allow override in this case */
1596 if (reiserfs_rupasov_hash(s)) {
1597 hash = YURA_HASH;
1598 }
Jeff Mahoney1d889d92009-03-30 14:02:20 -04001599 reiserfs_info(s, "FS seems to be empty, autodetect "
1600 "is using the default hash\n");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001601 break;
1602 }
1603 r5hash = GET_HASH_VALUE(r5_hash(de.de_name, de.de_namelen));
1604 teahash = GET_HASH_VALUE(keyed_hash(de.de_name, de.de_namelen));
1605 yurahash = GET_HASH_VALUE(yura_hash(de.de_name, de.de_namelen));
1606 if (((teahash == r5hash)
1607 &&
1608 (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num])))
1609 == r5hash)) || ((teahash == yurahash)
1610 && (yurahash ==
1611 GET_HASH_VALUE(deh_offset
1612 (&
1613 (de.
1614 de_deh[de.
1615 de_entry_num])))))
1616 || ((r5hash == yurahash)
1617 && (yurahash ==
1618 GET_HASH_VALUE(deh_offset
1619 (&(de.de_deh[de.de_entry_num])))))) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001620 reiserfs_warning(s, "reiserfs-2506", "Unable to "
1621 "automatically detect hash function. "
1622 "Please mount with -o "
1623 "hash={tea,rupasov,r5}");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001624 hash = UNSET_HASH;
1625 break;
1626 }
1627 if (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num]))) ==
1628 yurahash)
1629 hash = YURA_HASH;
1630 else if (GET_HASH_VALUE
1631 (deh_offset(&(de.de_deh[de.de_entry_num]))) == teahash)
1632 hash = TEA_HASH;
1633 else if (GET_HASH_VALUE
1634 (deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash)
1635 hash = R5_HASH;
1636 else {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001637 reiserfs_warning(s, "reiserfs-2506",
1638 "Unrecognised hash function");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001639 hash = UNSET_HASH;
1640 }
1641 } while (0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001643 pathrelse(&path);
1644 return hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645}
1646
1647// finds out which hash names are sorted with
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001648static int what_hash(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001650 __u32 code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001652 code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001654 /* reiserfs_hash_detect() == true if any of the hash mount options
1655 ** were used. We must check them to make sure the user isn't
1656 ** using a bad hash value
1657 */
1658 if (code == UNSET_HASH || reiserfs_hash_detect(s))
1659 code = find_hash_out(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001661 if (code != UNSET_HASH && reiserfs_hash_detect(s)) {
Jeff Mahoney0222e652009-03-30 14:02:44 -04001662 /* detection has found the hash, and we must check against the
1663 ** mount options
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001664 */
1665 if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001666 reiserfs_warning(s, "reiserfs-2507",
1667 "Error, %s hash detected, "
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001668 "unable to force rupasov hash",
1669 reiserfs_hashname(code));
1670 code = UNSET_HASH;
1671 } else if (reiserfs_tea_hash(s) && code != TEA_HASH) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001672 reiserfs_warning(s, "reiserfs-2508",
1673 "Error, %s hash detected, "
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001674 "unable to force tea hash",
1675 reiserfs_hashname(code));
1676 code = UNSET_HASH;
1677 } else if (reiserfs_r5_hash(s) && code != R5_HASH) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001678 reiserfs_warning(s, "reiserfs-2509",
1679 "Error, %s hash detected, "
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001680 "unable to force r5 hash",
1681 reiserfs_hashname(code));
1682 code = UNSET_HASH;
1683 }
1684 } else {
1685 /* find_hash_out was not called or could not determine the hash */
1686 if (reiserfs_rupasov_hash(s)) {
1687 code = YURA_HASH;
1688 } else if (reiserfs_tea_hash(s)) {
1689 code = TEA_HASH;
1690 } else if (reiserfs_r5_hash(s)) {
1691 code = R5_HASH;
1692 }
1693 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Jeff Mahoney0222e652009-03-30 14:02:44 -04001695 /* if we are mounted RW, and we have a new valid hash code, update
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001696 ** the super
1697 */
1698 if (code != UNSET_HASH &&
1699 !(s->s_flags & MS_RDONLY) &&
1700 code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
1701 set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
1702 }
1703 return code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704}
1705
1706// return pointer to appropriate function
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001707static hashf_t hash_function(struct super_block *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001709 switch (what_hash(s)) {
1710 case TEA_HASH:
1711 reiserfs_info(s, "Using tea hash to sort names\n");
1712 return keyed_hash;
1713 case YURA_HASH:
1714 reiserfs_info(s, "Using rupasov hash to sort names\n");
1715 return yura_hash;
1716 case R5_HASH:
1717 reiserfs_info(s, "Using r5 hash to sort names\n");
1718 return r5_hash;
1719 }
1720 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721}
1722
1723// this is used to set up correct value for old partitions
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001724static int function2code(hashf_t func)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001726 if (func == keyed_hash)
1727 return TEA_HASH;
1728 if (func == yura_hash)
1729 return YURA_HASH;
1730 if (func == r5_hash)
1731 return R5_HASH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001733 BUG(); // should never happen
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001735 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736}
1737
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001738#define SWARN(silent, s, id, ...) \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 if (!(silent)) \
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001740 reiserfs_warning(s, id, __VA_ARGS__)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001742static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001744 struct inode *root_inode;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001745 struct reiserfs_transaction_handle th;
1746 int old_format = 0;
1747 unsigned long blocks;
1748 unsigned int commit_max_age = 0;
1749 int jinit_done = 0;
1750 struct reiserfs_iget_args args;
1751 struct reiserfs_super_block *rs;
1752 char *jdev_name;
1753 struct reiserfs_sb_info *sbi;
1754 int errval = -EINVAL;
Jan Kara00b44192008-07-25 01:46:38 -07001755 char *qf_names[MAXQUOTAS] = {};
1756 unsigned int qfmt = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
Miklos Szeredicdf6ccc2008-02-08 04:21:47 -08001758 save_mount_options(s, data);
1759
Yan Burman01afb212006-12-06 20:39:01 -08001760 sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
Jeff Mahoneyb7b7fa42010-03-29 15:12:39 -04001761 if (!sbi)
1762 return -ENOMEM;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001763 s->s_fs_info = sbi;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001764 /* Set default values for options: non-aggressive tails, RO on errors */
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001765 sbi->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
1766 sbi->s_mount_opt |= (1 << REISERFS_ERROR_RO);
1767 sbi->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001768 /* no preallocation minimum, be smart in
1769 reiserfs_file_write instead */
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001770 sbi->s_alloc_options.preallocmin = 0;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001771 /* Preallocate by 16 blocks (17-1) at once */
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001772 sbi->s_alloc_options.preallocsize = 17;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001773 /* setup default block allocator options */
1774 reiserfs_init_alloc_options(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775
Artem Bityutskiy033369d2012-06-01 17:18:08 +03001776 spin_lock_init(&sbi->old_work_lock);
1777 INIT_DELAYED_WORK(&sbi->old_work, flush_old_commits);
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001778 mutex_init(&sbi->lock);
1779 sbi->lock_depth = -1;
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02001780
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001781 jdev_name = NULL;
1782 if (reiserfs_parse_options
1783 (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,
Jan Kara00b44192008-07-25 01:46:38 -07001784 &commit_max_age, qf_names, &qfmt) == 0) {
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001785 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001786 }
Jan Karac3aa0772011-12-21 20:17:10 +01001787 if (jdev_name && jdev_name[0]) {
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001788 sbi->s_jdev = kstrdup(jdev_name, GFP_KERNEL);
1789 if (!sbi->s_jdev) {
Jan Karac3aa0772011-12-21 20:17:10 +01001790 SWARN(silent, s, "", "Cannot allocate memory for "
1791 "journal device name");
1792 goto error;
1793 }
1794 }
Jan Kara00b44192008-07-25 01:46:38 -07001795#ifdef CONFIG_QUOTA
1796 handle_quota_files(s, qf_names, &qfmt);
1797#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001799 if (blocks) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001800 SWARN(silent, s, "jmacd-7", "resize option for remount only");
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001801 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001802 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001804 /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
1805 if (!read_super_block(s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
1806 old_format = 1;
1807 /* try new format (64-th 1k block), which can contain reiserfs super block */
1808 else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001809 SWARN(silent, s, "sh-2021", "can not find reiserfs on %s",
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001810 reiserfs_bdevname(s));
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001811 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001814 rs = SB_DISK_SUPER_BLOCK(s);
1815 /* Let's do basic sanity check to verify that underlying device is not
1816 smaller than the filesystem. If the check fails then abort and scream,
1817 because bad stuff will happen otherwise. */
1818 if (s->s_bdev && s->s_bdev->bd_inode
1819 && i_size_read(s->s_bdev->bd_inode) <
1820 sb_block_count(rs) * sb_blocksize(rs)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001821 SWARN(silent, s, "", "Filesystem cannot be "
1822 "mounted because it is bigger than the device");
1823 SWARN(silent, s, "", "You may need to run fsck "
1824 "or increase size of your LVM partition");
1825 SWARN(silent, s, "", "Or may be you forgot to "
1826 "reboot after fdisk when it told you to");
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001827 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001828 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001830 sbi->s_mount_state = SB_REISERFS_STATE(s);
1831 sbi->s_mount_state = REISERFS_VALID_FS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Jeff Mahoney6f010462006-09-30 23:28:43 -07001833 if ((errval = reiserfs_init_bitmap_cache(s))) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001834 SWARN(silent, s, "jmacd-8", "unable to read bitmap");
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001835 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001836 }
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001837
Jeff Mahoneyd2c89a42006-11-02 22:07:20 -08001838 errval = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839#ifdef CONFIG_REISERFS_CHECK
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001840 SWARN(silent, s, "", "CONFIG_REISERFS_CHECK is set ON");
1841 SWARN(silent, s, "", "- it is slow mode for debugging.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842#endif
1843
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001844 /* make data=ordered the default */
1845 if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) &&
1846 !reiserfs_data_writeback(s)) {
Artem Bityutskiyefaa33e2012-06-01 17:18:04 +03001847 sbi->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 }
1849
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001850 if (reiserfs_data_log(s)) {
1851 reiserfs_info(s, "using journaled data mode\n");
1852 } else if (reiserfs_data_ordered(s)) {
1853 reiserfs_info(s, "using ordered data mode\n");
1854 } else {
1855 reiserfs_info(s, "using writeback data mode\n");
1856 }
1857 if (reiserfs_barrier_flush(s)) {
1858 printk("reiserfs: using flush barriers\n");
1859 }
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08001860
Frederic Weisbecker37c69b92012-01-10 15:11:09 -08001861 // set_device_ro(s->s_dev, 1) ;
1862 if (journal_init(s, jdev_name, old_format, commit_max_age)) {
1863 SWARN(silent, s, "sh-2022",
1864 "unable to initialize journal space");
1865 goto error_unlocked;
1866 } else {
1867 jinit_done = 1; /* once this is set, journal_release must be called
1868 ** if we error out of the mount
1869 */
1870 }
1871
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001872 if (reread_meta_blocks(s)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001873 SWARN(silent, s, "jmacd-9",
1874 "unable to reread meta blocks after journal init");
Frederic Weisbecker9b467e62012-01-10 15:11:11 -08001875 goto error_unlocked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 }
1877
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001878 if (replay_only(s))
Frederic Weisbecker9b467e62012-01-10 15:11:11 -08001879 goto error_unlocked;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001880
1881 if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001882 SWARN(silent, s, "clm-7000",
1883 "Detected readonly device, marking FS readonly");
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001884 s->s_flags |= MS_RDONLY;
1885 }
1886 args.objectid = REISERFS_ROOT_OBJECTID;
1887 args.dirid = REISERFS_ROOT_PARENT_OBJECTID;
1888 root_inode =
1889 iget5_locked(s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor,
1890 reiserfs_init_locked_inode, (void *)(&args));
1891 if (!root_inode) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001892 SWARN(silent, s, "jmacd-10", "get root inode failed");
Frederic Weisbecker9b467e62012-01-10 15:11:11 -08001893 goto error_unlocked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 }
1895
Frederic Weisbecker9b467e62012-01-10 15:11:11 -08001896 /*
1897 * This path assumed to be called with the BKL in the old times.
1898 * Now we have inherited the big reiserfs lock from it and many
1899 * reiserfs helpers called in the mount path and elsewhere require
1900 * this lock to be held even if it's not always necessary. Let's be
1901 * conservative and hold it early. The window can be reduced after
1902 * careful review of the code.
1903 */
1904 reiserfs_write_lock(s);
1905
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001906 if (root_inode->i_state & I_NEW) {
1907 reiserfs_read_locked_inode(root_inode, &args);
1908 unlock_new_inode(root_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 }
1910
Al Viro48fde702012-01-08 22:15:13 -05001911 s->s_root = d_make_root(root_inode);
1912 if (!s->s_root)
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001913 goto error;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001914 // define and initialize hash function
1915 sbi->s_hash_function = hash_function(s);
1916 if (sbi->s_hash_function == NULL) {
1917 dput(s->s_root);
1918 s->s_root = NULL;
1919 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001921
1922 if (is_reiserfs_3_5(rs)
1923 || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1))
1924 set_bit(REISERFS_3_5, &(sbi->s_properties));
Jeff Mahoneye1fabd32006-09-30 23:28:40 -07001925 else if (old_format)
1926 set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties));
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001927 else
1928 set_bit(REISERFS_3_6, &(sbi->s_properties));
1929
1930 if (!(s->s_flags & MS_RDONLY)) {
1931
1932 errval = journal_begin(&th, s, 1);
1933 if (errval) {
1934 dput(s->s_root);
1935 s->s_root = NULL;
1936 goto error;
1937 }
1938 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
1939
1940 set_sb_umount_state(rs, REISERFS_ERROR_FS);
1941 set_sb_fs_state(rs, 0);
1942
Jeff Mahoneycb680c12007-10-18 23:39:27 -07001943 /* Clear out s_bmap_nr if it would wrap. We can handle this
1944 * case, but older revisions can't. This will cause the
1945 * file system to fail mount on those older implementations,
1946 * avoiding corruption. -jeffm */
1947 if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
1948 sb_bmap_nr(rs) != 0) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04001949 reiserfs_warning(s, "super-2030", "This file system "
Jeff Mahoneycb680c12007-10-18 23:39:27 -07001950 "claims to use %u bitmap blocks in "
1951 "its super block, but requires %u. "
1952 "Clearing to zero.", sb_bmap_nr(rs),
1953 reiserfs_bmap_count(s));
1954
1955 set_sb_bmap_nr(rs, 0);
1956 }
1957
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001958 if (old_format_only(s)) {
1959 /* filesystem of format 3.5 either with standard or non-standard
1960 journal */
1961 if (convert_reiserfs(s)) {
1962 /* and -o conv is given */
1963 if (!silent)
1964 reiserfs_info(s,
1965 "converting 3.5 filesystem to the 3.6 format");
1966
1967 if (is_reiserfs_3_5(rs))
1968 /* put magic string of 3.6 format. 2.2 will not be able to
1969 mount this filesystem anymore */
1970 memcpy(rs->s_v1.s_magic,
1971 reiserfs_3_6_magic_string,
1972 sizeof
1973 (reiserfs_3_6_magic_string));
1974
1975 set_sb_version(rs, REISERFS_VERSION_2);
1976 reiserfs_convert_objectid_map_v1(s);
1977 set_bit(REISERFS_3_6, &(sbi->s_properties));
1978 clear_bit(REISERFS_3_5, &(sbi->s_properties));
1979 } else if (!silent) {
1980 reiserfs_info(s, "using 3.5.x disk format\n");
1981 }
Jeff Mahoney702d21c2009-03-30 14:02:16 -04001982 } else
1983 set_sb_mnt_count(rs, sb_mnt_count(rs) + 1);
1984
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001985
1986 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
1987 errval = journal_end(&th, s, 1);
1988 if (errval) {
1989 dput(s->s_root);
1990 s->s_root = NULL;
1991 goto error;
1992 }
1993
Al Viroedcc37a2009-05-03 06:00:05 -04001994 if ((errval = reiserfs_lookup_privroot(s)) ||
1995 (errval = reiserfs_xattr_init(s, s->s_flags))) {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07001996 dput(s->s_root);
1997 s->s_root = NULL;
1998 goto error;
1999 }
2000
2001 /* look for files which were to be removed in previous session */
2002 finish_unfinished(s);
2003 } else {
2004 if (old_format_only(s) && !silent) {
2005 reiserfs_info(s, "using 3.5.x disk format\n");
2006 }
2007
Al Viroedcc37a2009-05-03 06:00:05 -04002008 if ((errval = reiserfs_lookup_privroot(s)) ||
2009 (errval = reiserfs_xattr_init(s, s->s_flags))) {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002010 dput(s->s_root);
2011 s->s_root = NULL;
2012 goto error;
2013 }
2014 }
2015 // mark hash in super block: it could be unset. overwrite should be ok
2016 set_sb_hash_function_code(rs, function2code(sbi->s_hash_function));
2017
2018 handle_attrs(s);
2019
2020 reiserfs_proc_info_init(s);
2021
2022 init_waitqueue_head(&(sbi->s_wait));
2023 spin_lock_init(&sbi->bitmap_lock);
2024
Frederic Weisbecker8ebc4232009-04-07 04:19:49 +02002025 reiserfs_write_unlock(s);
2026
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002027 return (0);
2028
Jan Kara00b44192008-07-25 01:46:38 -07002029error:
Jeff Mahoneyb7b7fa42010-03-29 15:12:39 -04002030 reiserfs_write_unlock(s);
2031
Frederic Weisbeckerf32485b2012-01-10 15:11:07 -08002032error_unlocked:
2033 /* kill the commit thread, free journal ram */
2034 if (jinit_done) {
2035 reiserfs_write_lock(s);
2036 journal_release_error(NULL, s);
2037 reiserfs_write_unlock(s);
2038 }
2039
Artem Bityutskiy033369d2012-06-01 17:18:08 +03002040 cancel_delayed_work_sync(&REISERFS_SB(s)->old_work);
2041
Jeff Mahoney50652272006-09-30 23:28:44 -07002042 reiserfs_free_bitmap_cache(s);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002043 if (SB_BUFFER_WITH_SB(s))
2044 brelse(SB_BUFFER_WITH_SB(s));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045#ifdef CONFIG_QUOTA
Jeff Mahoney50652272006-09-30 23:28:44 -07002046 {
2047 int j;
Jan Kara00b44192008-07-25 01:46:38 -07002048 for (j = 0; j < MAXQUOTAS; j++)
2049 kfree(qf_names[j]);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002050 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051#endif
James Lamanna833d3042005-10-30 15:00:16 -08002052 kfree(sbi);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002054 s->s_fs_info = NULL;
2055 return errval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056}
2057
David Howells726c3342006-06-23 02:02:58 -07002058static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059{
David Howells726c3342006-06-23 02:02:58 -07002060 struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(dentry->d_sb);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002061
2062 buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize));
2063 buf->f_bfree = sb_free_blocks(rs);
2064 buf->f_bavail = buf->f_bfree;
2065 buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
David Howells726c3342006-06-23 02:02:58 -07002066 buf->f_bsize = dentry->d_sb->s_blocksize;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002067 /* changed to accommodate gcc folks. */
2068 buf->f_type = REISERFS_SUPER_MAGIC;
Coly Li651d0622009-04-02 16:59:41 -07002069 buf->f_fsid.val[0] = (u32)crc32_le(0, rs->s_uuid, sizeof(rs->s_uuid)/2);
2070 buf->f_fsid.val[1] = (u32)crc32_le(0, rs->s_uuid + sizeof(rs->s_uuid)/2,
2071 sizeof(rs->s_uuid)/2);
2072
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002073 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074}
2075
2076#ifdef CONFIG_QUOTA
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077static int reiserfs_write_dquot(struct dquot *dquot)
2078{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002079 struct reiserfs_transaction_handle th;
2080 int ret, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002082 reiserfs_write_lock(dquot->dq_sb);
2083 ret =
2084 journal_begin(&th, dquot->dq_sb,
2085 REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
2086 if (ret)
2087 goto out;
2088 ret = dquot_commit(dquot);
2089 err =
2090 journal_end(&th, dquot->dq_sb,
2091 REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
2092 if (!ret && err)
2093 ret = err;
2094 out:
2095 reiserfs_write_unlock(dquot->dq_sb);
2096 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097}
2098
2099static int reiserfs_acquire_dquot(struct dquot *dquot)
2100{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002101 struct reiserfs_transaction_handle th;
2102 int ret, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002104 reiserfs_write_lock(dquot->dq_sb);
2105 ret =
2106 journal_begin(&th, dquot->dq_sb,
2107 REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
2108 if (ret)
2109 goto out;
2110 ret = dquot_acquire(dquot);
2111 err =
2112 journal_end(&th, dquot->dq_sb,
2113 REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
2114 if (!ret && err)
2115 ret = err;
2116 out:
2117 reiserfs_write_unlock(dquot->dq_sb);
2118 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119}
2120
2121static int reiserfs_release_dquot(struct dquot *dquot)
2122{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002123 struct reiserfs_transaction_handle th;
2124 int ret, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002126 reiserfs_write_lock(dquot->dq_sb);
2127 ret =
2128 journal_begin(&th, dquot->dq_sb,
2129 REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
Jan Kara9c3013e2007-09-11 15:23:29 -07002130 if (ret) {
2131 /* Release dquot anyway to avoid endless cycle in dqput() */
2132 dquot_release(dquot);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002133 goto out;
Jan Kara9c3013e2007-09-11 15:23:29 -07002134 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002135 ret = dquot_release(dquot);
2136 err =
2137 journal_end(&th, dquot->dq_sb,
2138 REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
2139 if (!ret && err)
2140 ret = err;
2141 out:
2142 reiserfs_write_unlock(dquot->dq_sb);
2143 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144}
2145
2146static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
2147{
Jan Kara45065672008-07-25 01:46:37 -07002148 /* Are we journaling quotas? */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002149 if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
2150 REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
2151 dquot_mark_dquot_dirty(dquot);
2152 return reiserfs_write_dquot(dquot);
2153 } else
2154 return dquot_mark_dquot_dirty(dquot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155}
2156
2157static int reiserfs_write_info(struct super_block *sb, int type)
2158{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002159 struct reiserfs_transaction_handle th;
2160 int ret, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002162 /* Data block + inode block */
2163 reiserfs_write_lock(sb);
2164 ret = journal_begin(&th, sb, 2);
2165 if (ret)
2166 goto out;
2167 ret = dquot_commit_info(sb, type);
2168 err = journal_end(&th, sb, 2);
2169 if (!ret && err)
2170 ret = err;
2171 out:
2172 reiserfs_write_unlock(sb);
2173 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174}
2175
2176/*
Christoph Hellwig84de8562005-06-23 00:09:16 -07002177 * Turn on quotas during mount time - we need to find the quota file and such...
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178 */
2179static int reiserfs_quota_on_mount(struct super_block *sb, int type)
2180{
Christoph Hellwig287a8092010-05-19 07:16:45 -04002181 return dquot_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
2182 REISERFS_SB(sb)->s_jquota_fmt, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183}
2184
2185/*
2186 * Standard function to be called on quota_on
2187 */
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002188static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
Jan Karaf00c9e42010-09-15 17:38:58 +02002189 struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002191 int err;
Jan Karad5dee5c2008-04-28 02:16:23 -07002192 struct inode *inode;
Jan Kara5d4f7fd2008-07-25 01:46:36 -07002193 struct reiserfs_transaction_handle th;
Jan Karac3aa0772011-12-21 20:17:10 +01002194 int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
Jan Karac3aa0772011-12-21 20:17:10 +01002196 if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002197 return -EINVAL;
Christoph Hellwig307ae182010-05-19 07:16:43 -04002198
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002199 /* Quotafile not on the same filesystem? */
Al Virod8c95842011-12-07 18:16:57 -05002200 if (path->dentry->d_sb != sb) {
Al Viro77e69da2008-08-01 04:29:18 -04002201 err = -EXDEV;
2202 goto out;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002203 }
Jan Karaf00c9e42010-09-15 17:38:58 +02002204 inode = path->dentry->d_inode;
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002205 /* We must not pack tails for quota files on reiserfs for quota IO to work */
Jan Karad5dee5c2008-04-28 02:16:23 -07002206 if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
2207 err = reiserfs_unpack(inode, NULL);
2208 if (err) {
Jeff Mahoney45b03d52009-03-30 14:02:21 -04002209 reiserfs_warning(sb, "super-6520",
2210 "Unpacking tail of quota file failed"
Jan Karad5dee5c2008-04-28 02:16:23 -07002211 " (%d). Cannot turn on quotas.", err);
Al Viro77e69da2008-08-01 04:29:18 -04002212 err = -EINVAL;
2213 goto out;
Jan Karad5dee5c2008-04-28 02:16:23 -07002214 }
2215 mark_inode_dirty(inode);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002216 }
Jan Kara5d4f7fd2008-07-25 01:46:36 -07002217 /* Journaling quota? */
2218 if (REISERFS_SB(sb)->s_qf_names[type]) {
2219 /* Quotafile not of fs root? */
Jan Karaf00c9e42010-09-15 17:38:58 +02002220 if (path->dentry->d_parent != sb->s_root)
Jeff Mahoney45b03d52009-03-30 14:02:21 -04002221 reiserfs_warning(sb, "super-6521",
2222 "Quota file not on filesystem root. "
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002223 "Journalled quota will not work.");
Jan Kara5d4f7fd2008-07-25 01:46:36 -07002224 }
2225
2226 /*
2227 * When we journal data on quota file, we have to flush journal to see
2228 * all updates to the file when we bypass pagecache...
2229 */
2230 if (reiserfs_file_data_log(inode)) {
2231 /* Just start temporary transaction and finish it */
2232 err = journal_begin(&th, sb, 1);
2233 if (err)
Al Viro77e69da2008-08-01 04:29:18 -04002234 goto out;
Jan Kara5d4f7fd2008-07-25 01:46:36 -07002235 err = journal_end_sync(&th, sb, 1);
2236 if (err)
Al Viro77e69da2008-08-01 04:29:18 -04002237 goto out;
Jan Kara5d4f7fd2008-07-25 01:46:36 -07002238 }
Jan Karaf00c9e42010-09-15 17:38:58 +02002239 err = dquot_quota_on(sb, type, format_id, path);
Al Viro77e69da2008-08-01 04:29:18 -04002240out:
Al Viro77e69da2008-08-01 04:29:18 -04002241 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242}
2243
2244/* Read data from quotafile - avoid pagecache and such because we cannot afford
2245 * acquiring the locks... As quota files are never truncated and quota code
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002246 * itself serializes the operations (and no one else should touch the files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 * we don't have to be afraid of races */
2248static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
2249 size_t len, loff_t off)
2250{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002251 struct inode *inode = sb_dqopt(sb)->files[type];
2252 unsigned long blk = off >> sb->s_blocksize_bits;
2253 int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
2254 size_t toread;
2255 struct buffer_head tmp_bh, *bh;
2256 loff_t i_size = i_size_read(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002258 if (off > i_size)
2259 return 0;
2260 if (off + len > i_size)
2261 len = i_size - off;
2262 toread = len;
2263 while (toread > 0) {
2264 tocopy =
2265 sb->s_blocksize - offset <
2266 toread ? sb->s_blocksize - offset : toread;
2267 tmp_bh.b_state = 0;
2268 /* Quota files are without tails so we can safely use this function */
2269 reiserfs_write_lock(sb);
2270 err = reiserfs_get_block(inode, blk, &tmp_bh, 0);
2271 reiserfs_write_unlock(sb);
2272 if (err)
2273 return err;
2274 if (!buffer_mapped(&tmp_bh)) /* A hole? */
2275 memset(data, 0, tocopy);
2276 else {
2277 bh = sb_bread(sb, tmp_bh.b_blocknr);
2278 if (!bh)
2279 return -EIO;
2280 memcpy(data, bh->b_data + offset, tocopy);
2281 brelse(bh);
2282 }
2283 offset = 0;
2284 toread -= tocopy;
2285 data += tocopy;
2286 blk++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002288 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289}
2290
2291/* Write to quotafile (we know the transaction is already started and has
2292 * enough credits) */
2293static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
2294 const char *data, size_t len, loff_t off)
2295{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002296 struct inode *inode = sb_dqopt(sb)->files[type];
2297 unsigned long blk = off >> sb->s_blocksize_bits;
2298 int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
2299 int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
2300 size_t towrite = len;
2301 struct buffer_head tmp_bh, *bh;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
Jan Kara9c3013e2007-09-11 15:23:29 -07002303 if (!current->journal_info) {
2304 printk(KERN_WARNING "reiserfs: Quota write (off=%Lu, len=%Lu)"
2305 " cancelled because transaction is not started.\n",
2306 (unsigned long long)off, (unsigned long long)len);
2307 return -EIO;
2308 }
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002309 while (towrite > 0) {
2310 tocopy = sb->s_blocksize - offset < towrite ?
2311 sb->s_blocksize - offset : towrite;
2312 tmp_bh.b_state = 0;
2313 err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
2314 if (err)
2315 goto out;
2316 if (offset || tocopy != sb->s_blocksize)
2317 bh = sb_bread(sb, tmp_bh.b_blocknr);
2318 else
2319 bh = sb_getblk(sb, tmp_bh.b_blocknr);
2320 if (!bh) {
2321 err = -EIO;
2322 goto out;
2323 }
2324 lock_buffer(bh);
2325 memcpy(bh->b_data + offset, data, tocopy);
2326 flush_dcache_page(bh->b_page);
2327 set_buffer_uptodate(bh);
2328 unlock_buffer(bh);
2329 reiserfs_prepare_for_journal(sb, bh, 1);
2330 journal_mark_dirty(current->journal_info, sb, bh);
2331 if (!journal_quota)
2332 reiserfs_add_ordered_list(inode, bh);
2333 brelse(bh);
2334 offset = 0;
2335 towrite -= tocopy;
2336 data += tocopy;
2337 blk++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 }
Jan Kara9c3013e2007-09-11 15:23:29 -07002339out:
Jan Kara67f16482012-04-25 21:28:12 +02002340 if (len == towrite)
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002341 return err;
2342 if (inode->i_size < off + len - towrite)
2343 i_size_write(inode, off + len - towrite);
2344 inode->i_version++;
2345 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
2346 mark_inode_dirty(inode);
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002347 return len - towrite;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348}
2349
2350#endif
2351
Al Viro152a0832010-07-25 00:46:55 +04002352static struct dentry *get_super_block(struct file_system_type *fs_type,
David Howells454e2392006-06-23 02:02:57 -07002353 int flags, const char *dev_name,
Al Viro152a0832010-07-25 00:46:55 +04002354 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355{
Al Viro152a0832010-07-25 00:46:55 +04002356 return mount_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357}
2358
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002359static int __init init_reiserfs_fs(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360{
2361 int ret;
2362
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002363 if ((ret = init_inodecache())) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 return ret;
2365 }
2366
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002367 reiserfs_proc_info_global_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002369 ret = register_filesystem(&reiserfs_fs_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370
2371 if (ret == 0) {
2372 return 0;
2373 }
2374
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002375 reiserfs_proc_info_global_done();
2376 destroy_inodecache();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377
2378 return ret;
2379}
2380
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002381static void __exit exit_reiserfs_fs(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382{
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002383 reiserfs_proc_info_global_done();
2384 unregister_filesystem(&reiserfs_fs_type);
2385 destroy_inodecache();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386}
2387
2388struct file_system_type reiserfs_fs_type = {
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002389 .owner = THIS_MODULE,
2390 .name = "reiserfs",
Al Viro152a0832010-07-25 00:46:55 +04002391 .mount = get_super_block,
David Howellsedc666e2006-10-11 01:22:14 -07002392 .kill_sb = reiserfs_kill_sb,
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002393 .fs_flags = FS_REQUIRES_DEV,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394};
2395
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002396MODULE_DESCRIPTION("ReiserFS journaled filesystem");
2397MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
2398MODULE_LICENSE("GPL");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
Linus Torvaldsbd4c6252005-07-12 20:21:28 -07002400module_init(init_reiserfs_fs);
2401module_exit(exit_reiserfs_fs);