exofs: Avoid using file_fsync()
[safe/jmp/linux-2.6] / fs / exofs / super.c
1 /*
2  * Copyright (C) 2005, 2006
3  * Avishay Traeger (avishay@gmail.com)
4  * Copyright (C) 2008, 2009
5  * Boaz Harrosh <bharrosh@panasas.com>
6  *
7  * Copyrights for code taken from ext2:
8  *     Copyright (C) 1992, 1993, 1994, 1995
9  *     Remy Card (card@masi.ibp.fr)
10  *     Laboratoire MASI - Institut Blaise Pascal
11  *     Universite Pierre et Marie Curie (Paris VI)
12  *     from
13  *     linux/fs/minix/inode.c
14  *     Copyright (C) 1991, 1992  Linus Torvalds
15  *
16  * This file is part of exofs.
17  *
18  * exofs is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation.  Since it is based on ext2, and the only
21  * valid version of GPL for the Linux kernel is version 2, the only valid
22  * version of GPL for exofs is version 2.
23  *
24  * exofs is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with exofs; if not, write to the Free Software
31  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
32  */
33
34 #include <linux/string.h>
35 #include <linux/parser.h>
36 #include <linux/vfs.h>
37 #include <linux/random.h>
38 #include <linux/exportfs.h>
39
40 #include "exofs.h"
41
42 /******************************************************************************
43  * MOUNT OPTIONS
44  *****************************************************************************/
45
46 /*
47  * struct to hold what we get from mount options
48  */
49 struct exofs_mountopt {
50         const char *dev_name;
51         uint64_t pid;
52         int timeout;
53 };
54
55 /*
56  * exofs-specific mount-time options.
57  */
58 enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
59
60 /*
61  * Our mount-time options.  These should ideally be 64-bit unsigned, but the
62  * kernel's parsing functions do not currently support that.  32-bit should be
63  * sufficient for most applications now.
64  */
65 static match_table_t tokens = {
66         {Opt_pid, "pid=%u"},
67         {Opt_to, "to=%u"},
68         {Opt_err, NULL}
69 };
70
71 /*
72  * The main option parsing method.  Also makes sure that all of the mandatory
73  * mount options were set.
74  */
75 static int parse_options(char *options, struct exofs_mountopt *opts)
76 {
77         char *p;
78         substring_t args[MAX_OPT_ARGS];
79         int option;
80         bool s_pid = false;
81
82         EXOFS_DBGMSG("parse_options %s\n", options);
83         /* defaults */
84         memset(opts, 0, sizeof(*opts));
85         opts->timeout = BLK_DEFAULT_SG_TIMEOUT;
86
87         while ((p = strsep(&options, ",")) != NULL) {
88                 int token;
89                 char str[32];
90
91                 if (!*p)
92                         continue;
93
94                 token = match_token(p, tokens, args);
95                 switch (token) {
96                 case Opt_pid:
97                         if (0 == match_strlcpy(str, &args[0], sizeof(str)))
98                                 return -EINVAL;
99                         opts->pid = simple_strtoull(str, NULL, 0);
100                         if (opts->pid < EXOFS_MIN_PID) {
101                                 EXOFS_ERR("Partition ID must be >= %u",
102                                           EXOFS_MIN_PID);
103                                 return -EINVAL;
104                         }
105                         s_pid = 1;
106                         break;
107                 case Opt_to:
108                         if (match_int(&args[0], &option))
109                                 return -EINVAL;
110                         if (option <= 0) {
111                                 EXOFS_ERR("Timout must be > 0");
112                                 return -EINVAL;
113                         }
114                         opts->timeout = option * HZ;
115                         break;
116                 }
117         }
118
119         if (!s_pid) {
120                 EXOFS_ERR("Need to specify the following options:\n");
121                 EXOFS_ERR("    -o pid=pid_no_to_use\n");
122                 return -EINVAL;
123         }
124
125         return 0;
126 }
127
128 /******************************************************************************
129  * INODE CACHE
130  *****************************************************************************/
131
132 /*
133  * Our inode cache.  Isn't it pretty?
134  */
135 static struct kmem_cache *exofs_inode_cachep;
136
137 /*
138  * Allocate an inode in the cache
139  */
140 static struct inode *exofs_alloc_inode(struct super_block *sb)
141 {
142         struct exofs_i_info *oi;
143
144         oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
145         if (!oi)
146                 return NULL;
147
148         oi->vfs_inode.i_version = 1;
149         return &oi->vfs_inode;
150 }
151
152 /*
153  * Remove an inode from the cache
154  */
155 static void exofs_destroy_inode(struct inode *inode)
156 {
157         kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
158 }
159
160 /*
161  * Initialize the inode
162  */
163 static void exofs_init_once(void *foo)
164 {
165         struct exofs_i_info *oi = foo;
166
167         inode_init_once(&oi->vfs_inode);
168 }
169
170 /*
171  * Create and initialize the inode cache
172  */
173 static int init_inodecache(void)
174 {
175         exofs_inode_cachep = kmem_cache_create("exofs_inode_cache",
176                                 sizeof(struct exofs_i_info), 0,
177                                 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
178                                 exofs_init_once);
179         if (exofs_inode_cachep == NULL)
180                 return -ENOMEM;
181         return 0;
182 }
183
184 /*
185  * Destroy the inode cache
186  */
187 static void destroy_inodecache(void)
188 {
189         kmem_cache_destroy(exofs_inode_cachep);
190 }
191
192 /******************************************************************************
193  * SUPERBLOCK FUNCTIONS
194  *****************************************************************************/
195 static const struct super_operations exofs_sops;
196 static const struct export_operations exofs_export_ops;
197
198 /*
199  * Write the superblock to the OSD
200  */
201 int exofs_sync_fs(struct super_block *sb, int wait)
202 {
203         struct exofs_sb_info *sbi;
204         struct exofs_fscb *fscb;
205         struct osd_request *or;
206         struct osd_obj_id obj;
207         int ret = -ENOMEM;
208
209         fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
210         if (!fscb) {
211                 EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
212                 return -ENOMEM;
213         }
214
215         lock_super(sb);
216         lock_kernel();
217         sbi = sb->s_fs_info;
218         fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
219         fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
220         fscb->s_magic = cpu_to_le16(sb->s_magic);
221         fscb->s_newfs = 0;
222
223         or = osd_start_request(sbi->s_dev, GFP_KERNEL);
224         if (unlikely(!or)) {
225                 EXOFS_ERR("exofs_write_super: osd_start_request failed.\n");
226                 goto out;
227         }
228
229         obj.partition = sbi->s_pid;
230         obj.id = EXOFS_SUPER_ID;
231         ret = osd_req_write_kern(or, &obj, 0, fscb, sizeof(*fscb));
232         if (unlikely(ret)) {
233                 EXOFS_ERR("exofs_write_super: osd_req_write_kern failed.\n");
234                 goto out;
235         }
236
237         ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
238         if (unlikely(ret)) {
239                 EXOFS_ERR("exofs_write_super: exofs_sync_op failed.\n");
240                 goto out;
241         }
242         sb->s_dirt = 0;
243
244 out:
245         if (or)
246                 osd_end_request(or);
247         unlock_kernel();
248         unlock_super(sb);
249         kfree(fscb);
250         return ret;
251 }
252
253 static void exofs_write_super(struct super_block *sb)
254 {
255         if (!(sb->s_flags & MS_RDONLY))
256                 exofs_sync_fs(sb, 1);
257         else
258                 sb->s_dirt = 0;
259 }
260
261 /*
262  * This function is called when the vfs is freeing the superblock.  We just
263  * need to free our own part.
264  */
265 static void exofs_put_super(struct super_block *sb)
266 {
267         int num_pend;
268         struct exofs_sb_info *sbi = sb->s_fs_info;
269
270         lock_kernel();
271
272         if (sb->s_dirt)
273                 exofs_write_super(sb);
274
275         /* make sure there are no pending commands */
276         for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
277              num_pend = atomic_read(&sbi->s_curr_pending)) {
278                 wait_queue_head_t wq;
279                 init_waitqueue_head(&wq);
280                 wait_event_timeout(wq,
281                                   (atomic_read(&sbi->s_curr_pending) == 0),
282                                   msecs_to_jiffies(100));
283         }
284
285         osduld_put_device(sbi->s_dev);
286         kfree(sb->s_fs_info);
287         sb->s_fs_info = NULL;
288
289         unlock_kernel();
290 }
291
292 /*
293  * Read the superblock from the OSD and fill in the fields
294  */
295 static int exofs_fill_super(struct super_block *sb, void *data, int silent)
296 {
297         struct inode *root;
298         struct exofs_mountopt *opts = data;
299         struct exofs_sb_info *sbi;      /*extended info                  */
300         struct exofs_fscb fscb;         /*on-disk superblock info        */
301         struct osd_request *or = NULL;
302         struct osd_obj_id obj;
303         int ret;
304
305         sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
306         if (!sbi)
307                 return -ENOMEM;
308         sb->s_fs_info = sbi;
309
310         /* use mount options to fill superblock */
311         sbi->s_dev = osduld_path_lookup(opts->dev_name);
312         if (IS_ERR(sbi->s_dev)) {
313                 ret = PTR_ERR(sbi->s_dev);
314                 sbi->s_dev = NULL;
315                 goto free_sbi;
316         }
317
318         sbi->s_pid = opts->pid;
319         sbi->s_timeout = opts->timeout;
320
321         /* fill in some other data by hand */
322         memset(sb->s_id, 0, sizeof(sb->s_id));
323         strcpy(sb->s_id, "exofs");
324         sb->s_blocksize = EXOFS_BLKSIZE;
325         sb->s_blocksize_bits = EXOFS_BLKSHIFT;
326         sb->s_maxbytes = MAX_LFS_FILESIZE;
327         atomic_set(&sbi->s_curr_pending, 0);
328         sb->s_bdev = NULL;
329         sb->s_dev = 0;
330
331         /* read data from on-disk superblock object */
332         obj.partition = sbi->s_pid;
333         obj.id = EXOFS_SUPER_ID;
334         exofs_make_credential(sbi->s_cred, &obj);
335
336         or = osd_start_request(sbi->s_dev, GFP_KERNEL);
337         if (unlikely(!or)) {
338                 if (!silent)
339                         EXOFS_ERR(
340                                "exofs_fill_super: osd_start_request failed.\n");
341                 ret = -ENOMEM;
342                 goto free_sbi;
343         }
344         ret = osd_req_read_kern(or, &obj, 0, &fscb, sizeof(fscb));
345         if (unlikely(ret)) {
346                 if (!silent)
347                         EXOFS_ERR(
348                                "exofs_fill_super: osd_req_read_kern failed.\n");
349                 ret = -ENOMEM;
350                 goto free_sbi;
351         }
352
353         ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
354         if (unlikely(ret)) {
355                 if (!silent)
356                         EXOFS_ERR("exofs_fill_super: exofs_sync_op failed.\n");
357                 ret = -EIO;
358                 goto free_sbi;
359         }
360
361         sb->s_magic = le16_to_cpu(fscb.s_magic);
362         sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
363         sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
364
365         /* make sure what we read from the object store is correct */
366         if (sb->s_magic != EXOFS_SUPER_MAGIC) {
367                 if (!silent)
368                         EXOFS_ERR("ERROR: Bad magic value\n");
369                 ret = -EINVAL;
370                 goto free_sbi;
371         }
372
373         /* start generation numbers from a random point */
374         get_random_bytes(&sbi->s_next_generation, sizeof(u32));
375         spin_lock_init(&sbi->s_next_gen_lock);
376
377         /* set up operation vectors */
378         sb->s_op = &exofs_sops;
379         sb->s_export_op = &exofs_export_ops;
380         root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
381         if (IS_ERR(root)) {
382                 EXOFS_ERR("ERROR: exofs_iget failed\n");
383                 ret = PTR_ERR(root);
384                 goto free_sbi;
385         }
386         sb->s_root = d_alloc_root(root);
387         if (!sb->s_root) {
388                 iput(root);
389                 EXOFS_ERR("ERROR: get root inode failed\n");
390                 ret = -ENOMEM;
391                 goto free_sbi;
392         }
393
394         if (!S_ISDIR(root->i_mode)) {
395                 dput(sb->s_root);
396                 sb->s_root = NULL;
397                 EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n",
398                        root->i_mode);
399                 ret = -EINVAL;
400                 goto free_sbi;
401         }
402
403         ret = 0;
404 out:
405         if (or)
406                 osd_end_request(or);
407         return ret;
408
409 free_sbi:
410         osduld_put_device(sbi->s_dev); /* NULL safe */
411         kfree(sbi);
412         goto out;
413 }
414
415 /*
416  * Set up the superblock (calls exofs_fill_super eventually)
417  */
418 static int exofs_get_sb(struct file_system_type *type,
419                           int flags, const char *dev_name,
420                           void *data, struct vfsmount *mnt)
421 {
422         struct exofs_mountopt opts;
423         int ret;
424
425         ret = parse_options(data, &opts);
426         if (ret)
427                 return ret;
428
429         opts.dev_name = dev_name;
430         return get_sb_nodev(type, flags, &opts, exofs_fill_super, mnt);
431 }
432
433 /*
434  * Return information about the file system state in the buffer.  This is used
435  * by the 'df' command, for example.
436  */
437 static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
438 {
439         struct super_block *sb = dentry->d_sb;
440         struct exofs_sb_info *sbi = sb->s_fs_info;
441         struct osd_obj_id obj = {sbi->s_pid, 0};
442         struct osd_attr attrs[] = {
443                 ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
444                         OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
445                 ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION,
446                         OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)),
447         };
448         uint64_t capacity = ULLONG_MAX;
449         uint64_t used = ULLONG_MAX;
450         struct osd_request *or;
451         uint8_t cred_a[OSD_CAP_LEN];
452         int ret;
453
454         /* get used/capacity attributes */
455         exofs_make_credential(cred_a, &obj);
456
457         or = osd_start_request(sbi->s_dev, GFP_KERNEL);
458         if (unlikely(!or)) {
459                 EXOFS_DBGMSG("exofs_statfs: osd_start_request failed.\n");
460                 return -ENOMEM;
461         }
462
463         osd_req_get_attributes(or, &obj);
464         osd_req_add_get_attr_list(or, attrs, ARRAY_SIZE(attrs));
465         ret = exofs_sync_op(or, sbi->s_timeout, cred_a);
466         if (unlikely(ret))
467                 goto out;
468
469         ret = extract_attr_from_req(or, &attrs[0]);
470         if (likely(!ret))
471                 capacity = get_unaligned_be64(attrs[0].val_ptr);
472         else
473                 EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
474
475         ret = extract_attr_from_req(or, &attrs[1]);
476         if (likely(!ret))
477                 used = get_unaligned_be64(attrs[1].val_ptr);
478         else
479                 EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n");
480
481         /* fill in the stats buffer */
482         buf->f_type = EXOFS_SUPER_MAGIC;
483         buf->f_bsize = EXOFS_BLKSIZE;
484         buf->f_blocks = (capacity >> EXOFS_BLKSHIFT);
485         buf->f_bfree = ((capacity - used) >> EXOFS_BLKSHIFT);
486         buf->f_bavail = buf->f_bfree;
487         buf->f_files = sbi->s_numfiles;
488         buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
489         buf->f_namelen = EXOFS_NAME_LEN;
490
491 out:
492         osd_end_request(or);
493         return ret;
494 }
495
496 static const struct super_operations exofs_sops = {
497         .alloc_inode    = exofs_alloc_inode,
498         .destroy_inode  = exofs_destroy_inode,
499         .write_inode    = exofs_write_inode,
500         .delete_inode   = exofs_delete_inode,
501         .put_super      = exofs_put_super,
502         .write_super    = exofs_write_super,
503         .sync_fs        = exofs_sync_fs,
504         .statfs         = exofs_statfs,
505 };
506
507 /******************************************************************************
508  * EXPORT OPERATIONS
509  *****************************************************************************/
510
511 struct dentry *exofs_get_parent(struct dentry *child)
512 {
513         unsigned long ino = exofs_parent_ino(child);
514
515         if (!ino)
516                 return NULL;
517
518         return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino));
519 }
520
521 static struct inode *exofs_nfs_get_inode(struct super_block *sb,
522                 u64 ino, u32 generation)
523 {
524         struct inode *inode;
525
526         inode = exofs_iget(sb, ino);
527         if (IS_ERR(inode))
528                 return ERR_CAST(inode);
529         if (generation && inode->i_generation != generation) {
530                 /* we didn't find the right inode.. */
531                 iput(inode);
532                 return ERR_PTR(-ESTALE);
533         }
534         return inode;
535 }
536
537 static struct dentry *exofs_fh_to_dentry(struct super_block *sb,
538                                 struct fid *fid, int fh_len, int fh_type)
539 {
540         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
541                                     exofs_nfs_get_inode);
542 }
543
544 static struct dentry *exofs_fh_to_parent(struct super_block *sb,
545                                 struct fid *fid, int fh_len, int fh_type)
546 {
547         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
548                                     exofs_nfs_get_inode);
549 }
550
551 static const struct export_operations exofs_export_ops = {
552         .fh_to_dentry = exofs_fh_to_dentry,
553         .fh_to_parent = exofs_fh_to_parent,
554         .get_parent = exofs_get_parent,
555 };
556
557 /******************************************************************************
558  * INSMOD/RMMOD
559  *****************************************************************************/
560
561 /*
562  * struct that describes this file system
563  */
564 static struct file_system_type exofs_type = {
565         .owner          = THIS_MODULE,
566         .name           = "exofs",
567         .get_sb         = exofs_get_sb,
568         .kill_sb        = generic_shutdown_super,
569 };
570
571 static int __init init_exofs(void)
572 {
573         int err;
574
575         err = init_inodecache();
576         if (err)
577                 goto out;
578
579         err = register_filesystem(&exofs_type);
580         if (err)
581                 goto out_d;
582
583         return 0;
584 out_d:
585         destroy_inodecache();
586 out:
587         return err;
588 }
589
590 static void __exit exit_exofs(void)
591 {
592         unregister_filesystem(&exofs_type);
593         destroy_inodecache();
594 }
595
596 MODULE_AUTHOR("Avishay Traeger <avishay@gmail.com>");
597 MODULE_DESCRIPTION("exofs");
598 MODULE_LICENSE("GPL");
599
600 module_init(init_exofs)
601 module_exit(exit_exofs)