GNU Linux-libre 4.9.337-gnu1
[releases.git] / fs / nilfs2 / dat.c
1 /*
2  * dat.c - NILFS disk address translation.
3  *
4  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * Written by Koji Sato.
17  */
18
19 #include <linux/types.h>
20 #include <linux/buffer_head.h>
21 #include <linux/string.h>
22 #include <linux/errno.h>
23 #include "nilfs.h"
24 #include "mdt.h"
25 #include "alloc.h"
26 #include "dat.h"
27
28
29 #define NILFS_CNO_MIN   ((__u64)1)
30 #define NILFS_CNO_MAX   (~(__u64)0)
31
32 /**
33  * struct nilfs_dat_info - on-memory private data of DAT file
34  * @mi: on-memory private data of metadata file
35  * @palloc_cache: persistent object allocator cache of DAT file
36  * @shadow: shadow map of DAT file
37  */
38 struct nilfs_dat_info {
39         struct nilfs_mdt_info mi;
40         struct nilfs_palloc_cache palloc_cache;
41         struct nilfs_shadow_map shadow;
42 };
43
44 static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)
45 {
46         return (struct nilfs_dat_info *)NILFS_MDT(dat);
47 }
48
49 static int nilfs_dat_prepare_entry(struct inode *dat,
50                                    struct nilfs_palloc_req *req, int create)
51 {
52         return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr,
53                                             create, &req->pr_entry_bh);
54 }
55
56 static void nilfs_dat_commit_entry(struct inode *dat,
57                                    struct nilfs_palloc_req *req)
58 {
59         mark_buffer_dirty(req->pr_entry_bh);
60         nilfs_mdt_mark_dirty(dat);
61         brelse(req->pr_entry_bh);
62 }
63
64 static void nilfs_dat_abort_entry(struct inode *dat,
65                                   struct nilfs_palloc_req *req)
66 {
67         brelse(req->pr_entry_bh);
68 }
69
70 int nilfs_dat_prepare_alloc(struct inode *dat, struct nilfs_palloc_req *req)
71 {
72         int ret;
73
74         ret = nilfs_palloc_prepare_alloc_entry(dat, req);
75         if (ret < 0)
76                 return ret;
77
78         ret = nilfs_dat_prepare_entry(dat, req, 1);
79         if (ret < 0)
80                 nilfs_palloc_abort_alloc_entry(dat, req);
81
82         return ret;
83 }
84
85 void nilfs_dat_commit_alloc(struct inode *dat, struct nilfs_palloc_req *req)
86 {
87         struct nilfs_dat_entry *entry;
88         void *kaddr;
89
90         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
91         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
92                                              req->pr_entry_bh, kaddr);
93         entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
94         entry->de_end = cpu_to_le64(NILFS_CNO_MAX);
95         entry->de_blocknr = cpu_to_le64(0);
96         kunmap_atomic(kaddr);
97
98         nilfs_palloc_commit_alloc_entry(dat, req);
99         nilfs_dat_commit_entry(dat, req);
100 }
101
102 void nilfs_dat_abort_alloc(struct inode *dat, struct nilfs_palloc_req *req)
103 {
104         nilfs_dat_abort_entry(dat, req);
105         nilfs_palloc_abort_alloc_entry(dat, req);
106 }
107
108 static void nilfs_dat_commit_free(struct inode *dat,
109                                   struct nilfs_palloc_req *req)
110 {
111         struct nilfs_dat_entry *entry;
112         void *kaddr;
113
114         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
115         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
116                                              req->pr_entry_bh, kaddr);
117         entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
118         entry->de_end = cpu_to_le64(NILFS_CNO_MIN);
119         entry->de_blocknr = cpu_to_le64(0);
120         kunmap_atomic(kaddr);
121
122         nilfs_dat_commit_entry(dat, req);
123
124         if (unlikely(req->pr_desc_bh == NULL || req->pr_bitmap_bh == NULL)) {
125                 nilfs_error(dat->i_sb,
126                             "state inconsistency probably due to duplicate use of vblocknr = %llu",
127                             (unsigned long long)req->pr_entry_nr);
128                 return;
129         }
130         nilfs_palloc_commit_free_entry(dat, req);
131 }
132
133 int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
134 {
135         int ret;
136
137         ret = nilfs_dat_prepare_entry(dat, req, 0);
138         WARN_ON(ret == -ENOENT);
139         return ret;
140 }
141
142 void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
143                             sector_t blocknr)
144 {
145         struct nilfs_dat_entry *entry;
146         void *kaddr;
147
148         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
149         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
150                                              req->pr_entry_bh, kaddr);
151         entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat));
152         entry->de_blocknr = cpu_to_le64(blocknr);
153         kunmap_atomic(kaddr);
154
155         nilfs_dat_commit_entry(dat, req);
156 }
157
158 int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
159 {
160         struct nilfs_dat_entry *entry;
161         sector_t blocknr;
162         void *kaddr;
163         int ret;
164
165         ret = nilfs_dat_prepare_entry(dat, req, 0);
166         if (ret < 0) {
167                 WARN_ON(ret == -ENOENT);
168                 return ret;
169         }
170
171         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
172         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
173                                              req->pr_entry_bh, kaddr);
174         blocknr = le64_to_cpu(entry->de_blocknr);
175         kunmap_atomic(kaddr);
176
177         if (blocknr == 0) {
178                 ret = nilfs_palloc_prepare_free_entry(dat, req);
179                 if (ret < 0) {
180                         nilfs_dat_abort_entry(dat, req);
181                         return ret;
182                 }
183         }
184
185         return 0;
186 }
187
188 void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
189                           int dead)
190 {
191         struct nilfs_dat_entry *entry;
192         __u64 start, end;
193         sector_t blocknr;
194         void *kaddr;
195
196         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
197         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
198                                              req->pr_entry_bh, kaddr);
199         end = start = le64_to_cpu(entry->de_start);
200         if (!dead) {
201                 end = nilfs_mdt_cno(dat);
202                 WARN_ON(start > end);
203         }
204         entry->de_end = cpu_to_le64(end);
205         blocknr = le64_to_cpu(entry->de_blocknr);
206         kunmap_atomic(kaddr);
207
208         if (blocknr == 0)
209                 nilfs_dat_commit_free(dat, req);
210         else
211                 nilfs_dat_commit_entry(dat, req);
212 }
213
214 void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
215 {
216         struct nilfs_dat_entry *entry;
217         __u64 start;
218         sector_t blocknr;
219         void *kaddr;
220
221         kaddr = kmap_atomic(req->pr_entry_bh->b_page);
222         entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
223                                              req->pr_entry_bh, kaddr);
224         start = le64_to_cpu(entry->de_start);
225         blocknr = le64_to_cpu(entry->de_blocknr);
226         kunmap_atomic(kaddr);
227
228         if (start == nilfs_mdt_cno(dat) && blocknr == 0)
229                 nilfs_palloc_abort_free_entry(dat, req);
230         nilfs_dat_abort_entry(dat, req);
231 }
232
233 int nilfs_dat_prepare_update(struct inode *dat,
234                              struct nilfs_palloc_req *oldreq,
235                              struct nilfs_palloc_req *newreq)
236 {
237         int ret;
238
239         ret = nilfs_dat_prepare_end(dat, oldreq);
240         if (!ret) {
241                 ret = nilfs_dat_prepare_alloc(dat, newreq);
242                 if (ret < 0)
243                         nilfs_dat_abort_end(dat, oldreq);
244         }
245         return ret;
246 }
247
248 void nilfs_dat_commit_update(struct inode *dat,
249                              struct nilfs_palloc_req *oldreq,
250                              struct nilfs_palloc_req *newreq, int dead)
251 {
252         nilfs_dat_commit_end(dat, oldreq, dead);
253         nilfs_dat_commit_alloc(dat, newreq);
254 }
255
256 void nilfs_dat_abort_update(struct inode *dat,
257                             struct nilfs_palloc_req *oldreq,
258                             struct nilfs_palloc_req *newreq)
259 {
260         nilfs_dat_abort_end(dat, oldreq);
261         nilfs_dat_abort_alloc(dat, newreq);
262 }
263
264 /**
265  * nilfs_dat_mark_dirty -
266  * @dat: DAT file inode
267  * @vblocknr: virtual block number
268  *
269  * Description:
270  *
271  * Return Value: On success, 0 is returned. On error, one of the following
272  * negative error codes is returned.
273  *
274  * %-EIO - I/O error.
275  *
276  * %-ENOMEM - Insufficient amount of memory available.
277  */
278 int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
279 {
280         struct nilfs_palloc_req req;
281         int ret;
282
283         req.pr_entry_nr = vblocknr;
284         ret = nilfs_dat_prepare_entry(dat, &req, 0);
285         if (ret == 0)
286                 nilfs_dat_commit_entry(dat, &req);
287         return ret;
288 }
289
290 /**
291  * nilfs_dat_freev - free virtual block numbers
292  * @dat: DAT file inode
293  * @vblocknrs: array of virtual block numbers
294  * @nitems: number of virtual block numbers
295  *
296  * Description: nilfs_dat_freev() frees the virtual block numbers specified by
297  * @vblocknrs and @nitems.
298  *
299  * Return Value: On success, 0 is returned. On error, one of the following
300  * negative error codes is returned.
301  *
302  * %-EIO - I/O error.
303  *
304  * %-ENOMEM - Insufficient amount of memory available.
305  *
306  * %-ENOENT - The virtual block number have not been allocated.
307  */
308 int nilfs_dat_freev(struct inode *dat, __u64 *vblocknrs, size_t nitems)
309 {
310         return nilfs_palloc_freev(dat, vblocknrs, nitems);
311 }
312
313 /**
314  * nilfs_dat_move - change a block number
315  * @dat: DAT file inode
316  * @vblocknr: virtual block number
317  * @blocknr: block number
318  *
319  * Description: nilfs_dat_move() changes the block number associated with
320  * @vblocknr to @blocknr.
321  *
322  * Return Value: On success, 0 is returned. On error, one of the following
323  * negative error codes is returned.
324  *
325  * %-EIO - I/O error.
326  *
327  * %-ENOMEM - Insufficient amount of memory available.
328  */
329 int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
330 {
331         struct buffer_head *entry_bh;
332         struct nilfs_dat_entry *entry;
333         void *kaddr;
334         int ret;
335
336         ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);
337         if (ret < 0)
338                 return ret;
339
340         /*
341          * The given disk block number (blocknr) is not yet written to
342          * the device at this point.
343          *
344          * To prevent nilfs_dat_translate() from returning the
345          * uncommitted block number, this makes a copy of the entry
346          * buffer and redirects nilfs_dat_translate() to the copy.
347          */
348         if (!buffer_nilfs_redirected(entry_bh)) {
349                 ret = nilfs_mdt_freeze_buffer(dat, entry_bh);
350                 if (ret) {
351                         brelse(entry_bh);
352                         return ret;
353                 }
354         }
355
356         kaddr = kmap_atomic(entry_bh->b_page);
357         entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
358         if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {
359                 nilfs_msg(dat->i_sb, KERN_CRIT,
360                           "%s: invalid vblocknr = %llu, [%llu, %llu)",
361                           __func__, (unsigned long long)vblocknr,
362                           (unsigned long long)le64_to_cpu(entry->de_start),
363                           (unsigned long long)le64_to_cpu(entry->de_end));
364                 kunmap_atomic(kaddr);
365                 brelse(entry_bh);
366                 return -EINVAL;
367         }
368         WARN_ON(blocknr == 0);
369         entry->de_blocknr = cpu_to_le64(blocknr);
370         kunmap_atomic(kaddr);
371
372         mark_buffer_dirty(entry_bh);
373         nilfs_mdt_mark_dirty(dat);
374
375         brelse(entry_bh);
376
377         return 0;
378 }
379
380 /**
381  * nilfs_dat_translate - translate a virtual block number to a block number
382  * @dat: DAT file inode
383  * @vblocknr: virtual block number
384  * @blocknrp: pointer to a block number
385  *
386  * Description: nilfs_dat_translate() maps the virtual block number @vblocknr
387  * to the corresponding block number.
388  *
389  * Return Value: On success, 0 is returned and the block number associated
390  * with @vblocknr is stored in the place pointed by @blocknrp. On error, one
391  * of the following negative error codes is returned.
392  *
393  * %-EIO - I/O error.
394  *
395  * %-ENOMEM - Insufficient amount of memory available.
396  *
397  * %-ENOENT - A block number associated with @vblocknr does not exist.
398  */
399 int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
400 {
401         struct buffer_head *entry_bh, *bh;
402         struct nilfs_dat_entry *entry;
403         sector_t blocknr;
404         void *kaddr;
405         int ret;
406
407         ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);
408         if (ret < 0)
409                 return ret;
410
411         if (!nilfs_doing_gc() && buffer_nilfs_redirected(entry_bh)) {
412                 bh = nilfs_mdt_get_frozen_buffer(dat, entry_bh);
413                 if (bh) {
414                         WARN_ON(!buffer_uptodate(bh));
415                         brelse(entry_bh);
416                         entry_bh = bh;
417                 }
418         }
419
420         kaddr = kmap_atomic(entry_bh->b_page);
421         entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
422         blocknr = le64_to_cpu(entry->de_blocknr);
423         if (blocknr == 0) {
424                 ret = -ENOENT;
425                 goto out;
426         }
427         *blocknrp = blocknr;
428
429  out:
430         kunmap_atomic(kaddr);
431         brelse(entry_bh);
432         return ret;
433 }
434
435 ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned int visz,
436                             size_t nvi)
437 {
438         struct buffer_head *entry_bh;
439         struct nilfs_dat_entry *entry;
440         struct nilfs_vinfo *vinfo = buf;
441         __u64 first, last;
442         void *kaddr;
443         unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block;
444         int i, j, n, ret;
445
446         for (i = 0; i < nvi; i += n) {
447                 ret = nilfs_palloc_get_entry_block(dat, vinfo->vi_vblocknr,
448                                                    0, &entry_bh);
449                 if (ret < 0)
450                         return ret;
451                 kaddr = kmap_atomic(entry_bh->b_page);
452                 /* last virtual block number in this block */
453                 first = vinfo->vi_vblocknr;
454                 do_div(first, entries_per_block);
455                 first *= entries_per_block;
456                 last = first + entries_per_block - 1;
457                 for (j = i, n = 0;
458                      j < nvi && vinfo->vi_vblocknr >= first &&
459                              vinfo->vi_vblocknr <= last;
460                      j++, n++, vinfo = (void *)vinfo + visz) {
461                         entry = nilfs_palloc_block_get_entry(
462                                 dat, vinfo->vi_vblocknr, entry_bh, kaddr);
463                         vinfo->vi_start = le64_to_cpu(entry->de_start);
464                         vinfo->vi_end = le64_to_cpu(entry->de_end);
465                         vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr);
466                 }
467                 kunmap_atomic(kaddr);
468                 brelse(entry_bh);
469         }
470
471         return nvi;
472 }
473
474 /**
475  * nilfs_dat_read - read or get dat inode
476  * @sb: super block instance
477  * @entry_size: size of a dat entry
478  * @raw_inode: on-disk dat inode
479  * @inodep: buffer to store the inode
480  */
481 int nilfs_dat_read(struct super_block *sb, size_t entry_size,
482                    struct nilfs_inode *raw_inode, struct inode **inodep)
483 {
484         static struct lock_class_key dat_lock_key;
485         struct inode *dat;
486         struct nilfs_dat_info *di;
487         int err;
488
489         if (entry_size > sb->s_blocksize) {
490                 nilfs_msg(sb, KERN_ERR, "too large DAT entry size: %zu bytes",
491                           entry_size);
492                 return -EINVAL;
493         } else if (entry_size < NILFS_MIN_DAT_ENTRY_SIZE) {
494                 nilfs_msg(sb, KERN_ERR, "too small DAT entry size: %zu bytes",
495                           entry_size);
496                 return -EINVAL;
497         }
498
499         dat = nilfs_iget_locked(sb, NULL, NILFS_DAT_INO);
500         if (unlikely(!dat))
501                 return -ENOMEM;
502         if (!(dat->i_state & I_NEW))
503                 goto out;
504
505         err = nilfs_mdt_init(dat, NILFS_MDT_GFP, sizeof(*di));
506         if (err)
507                 goto failed;
508
509         err = nilfs_palloc_init_blockgroup(dat, entry_size);
510         if (err)
511                 goto failed;
512
513         di = NILFS_DAT_I(dat);
514         lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
515         nilfs_palloc_setup_cache(dat, &di->palloc_cache);
516         nilfs_mdt_setup_shadow_map(dat, &di->shadow);
517
518         err = nilfs_read_inode_common(dat, raw_inode);
519         if (err)
520                 goto failed;
521
522         unlock_new_inode(dat);
523  out:
524         *inodep = dat;
525         return 0;
526  failed:
527         iget_failed(dat);
528         return err;
529 }