]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/fs/nandfs/nandfs_bmap.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / fs / nandfs / nandfs_bmap.c
1 /*-
2  * Copyright (c) 2010-2012 Semihalf
3  * Copyright (c) 2008, 2009 Reinoud Zandijk
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/namei.h>
35 #include <sys/kernel.h>
36 #include <sys/stat.h>
37 #include <sys/buf.h>
38 #include <sys/bio.h>
39 #include <sys/proc.h>
40 #include <sys/mount.h>
41 #include <sys/vnode.h>
42 #include <sys/signalvar.h>
43 #include <sys/malloc.h>
44 #include <sys/dirent.h>
45 #include <sys/lockf.h>
46 #include <sys/ktr.h>
47
48 #include <vm/vm.h>
49 #include <vm/vm_extern.h>
50 #include <vm/vm_object.h>
51 #include <vm/vnode_pager.h>
52
53 #include <machine/_inttypes.h>
54
55 #include <vm/vm.h>
56 #include <vm/vm_extern.h>
57 #include <vm/vm_object.h>
58 #include <vm/vnode_pager.h>
59
60 #include "nandfs_mount.h"
61 #include "nandfs.h"
62 #include "nandfs_subr.h"
63 #include "bmap.h"
64
65 nandfs_lbn_t
66 nandfs_get_maxfilesize(struct nandfs_device *fsdev)
67 {
68
69         return (get_maxfilesize(fsdev));
70 }
71
72 int
73 nandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk,
74     nandfs_daddr_t *vblk)
75 {
76         int error = 0;
77
78         if (node->nn_ino == NANDFS_GC_INO && lblk >= 0)
79                 *vblk = lblk;
80         else
81                 error = bmap_lookup(node, lblk, vblk);
82
83         DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n",
84             __func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
85             (uintmax_t)*vblk));
86
87         if (error)
88                 nandfs_error("%s: returned %d", __func__, error);
89
90         return (error);
91 }
92
93 int
94 nandfs_bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk,
95     struct buf *bp)
96 {
97         struct nandfs_device *fsdev;
98         nandfs_daddr_t vblk;
99         int error;
100
101         fsdev = node->nn_nandfsdev;
102
103         vblk = 0;
104         if (node->nn_ino != NANDFS_DAT_INO) {
105                 error = nandfs_vblock_alloc(fsdev, &vblk);
106                 if (error)
107                         return (error);
108         }
109
110         nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED);
111         nandfs_vblk_set(bp, vblk);
112
113         error = bmap_insert_block(node, lblk, vblk);
114         if (error) {
115                 nandfs_vblock_free(fsdev, vblk);
116                 return (error);
117         }
118
119         return (0);
120 }
121
122 int
123 nandfs_bmap_dirty_blocks(struct nandfs_node *node, struct buf *bp, int force)
124 {
125         int error;
126
127         error = bmap_dirty_meta(node, bp->b_lblkno, force);
128         if (error)
129                 nandfs_error("%s: cannot dirty buffer %p\n",
130                     __func__, bp);
131
132         return (error);
133 }
134
135 static int
136 nandfs_bmap_update_mapping(struct nandfs_node *node, nandfs_lbn_t lblk,
137     nandfs_daddr_t blknr)
138 {
139         int error;
140
141         DPRINTF(BMAP,
142             ("%s: node: %p ino: %#jx lblk: %#jx vblk: %#jx\n",
143             __func__, node, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
144             (uintmax_t)blknr));
145
146         error = bmap_insert_block(node, lblk, blknr);
147
148         return (error);
149 }
150
151 int
152 nandfs_bmap_update_block(struct nandfs_node *node, struct buf *bp,
153     nandfs_lbn_t blknr)
154 {
155         nandfs_lbn_t lblk;
156         int error;
157
158         lblk = bp->b_lblkno;
159         nandfs_vblk_set(bp, blknr);
160
161         DPRINTF(BMAP, ("%s: node: %p ino: %#jx bp: %p lblk: %#jx blk: %#jx\n",
162             __func__, node, (uintmax_t)node->nn_ino, bp,
163             (uintmax_t)lblk, (uintmax_t)blknr));
164
165         error = nandfs_bmap_update_mapping(node, lblk, blknr);
166         if (error) {
167                 nandfs_error("%s: cannot update lblk:%jx to blk:%jx for "
168                     "node:%p, error:%d\n", __func__, (uintmax_t)lblk,
169                     (uintmax_t)blknr, node, error);
170                 return (error);
171         }
172
173         return (error);
174 }
175
176 int
177 nandfs_bmap_update_dat(struct nandfs_node *node, nandfs_daddr_t oldblk,
178     struct buf *bp)
179 {
180         struct nandfs_device *fsdev;
181         nandfs_daddr_t vblk = 0;
182         int error;
183
184         if (node->nn_ino == NANDFS_DAT_INO)
185                 return (0);
186
187         if (nandfs_buf_check(bp, NANDFS_VBLK_ASSIGNED)) {
188                 nandfs_buf_clear(bp, NANDFS_VBLK_ASSIGNED);
189                 return (0);
190         }
191
192         fsdev = node->nn_nandfsdev;
193
194         /* First alloc new virtual block.... */
195         error = nandfs_vblock_alloc(fsdev, &vblk);
196         if (error)
197                 return (error);
198
199         error = nandfs_bmap_update_block(node, bp, vblk);
200         if (error)
201                 return (error);
202
203         /* Then we can end up with old one */
204         nandfs_vblock_end(fsdev, oldblk);
205
206         DPRINTF(BMAP,
207             ("%s: ino %#jx block %#jx: update vblk %#jx to %#jx\n",
208             __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno,
209             (uintmax_t)oldblk, (uintmax_t)vblk));
210         return (error);
211 }
212
213 int
214 nandfs_bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t oblk,
215     nandfs_lbn_t nblk)
216 {
217         nandfs_lbn_t todo;
218         int error;
219
220         todo = oblk - nblk;
221
222         DPRINTF(BMAP, ("%s: node %p oblk %jx nblk %jx truncate by %jx\n",
223             __func__, node, oblk, nblk, todo));
224
225         error = bmap_truncate_mapping(node, oblk, todo);
226         if (error)
227                 return (error);
228
229         return (error);
230 }