nandfs_bmap.c revision 235537
1151497Sru/*-
275584Sru * Copyright (c) 2010-2012 Semihalf
375584Sru * Copyright (c) 2008, 2009 Reinoud Zandijk
475584Sru * All rights reserved.
575584Sru *
675584Sru * Redistribution and use in source and binary forms, with or without
775584Sru * modification, are permitted provided that the following conditions
875584Sru * are met:
975584Sru * 1. Redistributions of source code must retain the above copyright
10151497Sru *    notice, this list of conditions and the following disclaimer.
11151497Sru * 2. Redistributions in binary form must reproduce the above copyright
12151497Sru *    notice, this list of conditions and the following disclaimer in the
13151497Sru *    documentation and/or other materials provided with the distribution.
14151497Sru *
15151497Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16151497Sru * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17151497Sru * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18151497Sru * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19151497Sru * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20151497Sru * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21151497Sru * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22151497Sru * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23151497Sru * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24151497Sru * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25151497Sru *
26151497Sru * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud
27151497Sru */
28151497Sru
29151497Sru#include <sys/cdefs.h>
30151497Sru__FBSDID("$FreeBSD: head/sys/fs/nandfs/nandfs_bmap.c 235537 2012-05-17 10:11:18Z gber $");
31151497Sru
32151497Sru#include <sys/param.h>
33151497Sru#include <sys/systm.h>
34151497Sru#include <sys/namei.h>
35151497Sru#include <sys/kernel.h>
36151497Sru#include <sys/stat.h>
37151497Sru#include <sys/buf.h>
38151497Sru#include <sys/bio.h>
39151497Sru#include <sys/proc.h>
40151497Sru#include <sys/mount.h>
41151497Sru#include <sys/vnode.h>
42151497Sru#include <sys/signalvar.h>
43151497Sru#include <sys/malloc.h>
44151497Sru#include <sys/dirent.h>
45151497Sru#include <sys/lockf.h>
46151497Sru#include <sys/ktr.h>
47151497Sru
48151497Sru#include <vm/vm.h>
49151497Sru#include <vm/vm_extern.h>
50151497Sru#include <vm/vm_object.h>
51151497Sru#include <vm/vnode_pager.h>
52151497Sru
53151497Sru#include <machine/_inttypes.h>
54151497Sru
55151497Sru#include <vm/vm.h>
56151497Sru#include <vm/vm_extern.h>
57151497Sru#include <vm/vm_object.h>
58151497Sru#include <vm/vnode_pager.h>
59151497Sru
60151497Sru#include "nandfs_mount.h"
61151497Sru#include "nandfs.h"
62151497Sru#include "nandfs_subr.h"
63151497Sru#include "bmap.h"
64151497Sru
65151497Srunandfs_lbn_t
66151497Srunandfs_get_maxfilesize(struct nandfs_device *fsdev)
67151497Sru{
68151497Sru
69151497Sru	return (get_maxfilesize(fsdev));
70151497Sru}
71151497Sru
72151497Sruint
73151497Srunandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk,
74151497Sru    nandfs_daddr_t *vblk)
75151497Sru{
76151497Sru	int error = 0;
77151497Sru
78151497Sru	if (node->nn_ino == NANDFS_GC_INO && lblk >= 0)
79151497Sru		*vblk = lblk;
80151497Sru	else
81151497Sru		error = bmap_lookup(node, lblk, vblk);
82151497Sru
83151497Sru	DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n",
84151497Sru	    __func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
85151497Sru	    (uintmax_t)*vblk));
86151497Sru
87151497Sru	if (error)
88151497Sru		nandfs_error("%s: returned %d", __func__, error);
89151497Sru
90151497Sru	return (error);
91151497Sru}
92151497Sru
93151497Sruint
94151497Srunandfs_bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk,
95151497Sru    struct buf *bp)
96151497Sru{
97151497Sru	struct nandfs_device *fsdev;
98151497Sru	nandfs_daddr_t vblk;
99151497Sru	int error;
100151497Sru
101151497Sru	fsdev = node->nn_nandfsdev;
102151497Sru
103151497Sru	vblk = 0;
104151497Sru	if (node->nn_ino != NANDFS_DAT_INO) {
105151497Sru		error = nandfs_vblock_alloc(fsdev, &vblk);
106151497Sru		if (error)
107151497Sru			return (error);
108151497Sru	}
109151497Sru
110151497Sru	nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED);
111151497Sru	nandfs_vblk_set(bp, vblk);
112151497Sru
113151497Sru	error = bmap_insert_block(node, lblk, vblk);
114151497Sru	if (error) {
115151497Sru		nandfs_vblock_free(fsdev, vblk);
116151497Sru		return (error);
117151497Sru	}
118151497Sru
119151497Sru	return (0);
120151497Sru}
121151497Sru
122151497Sruint
123151497Srunandfs_bmap_dirty_blocks(struct nandfs_node *node, struct buf *bp, int force)
124151497Sru{
125151497Sru	int error;
126151497Sru
127151497Sru	error = bmap_dirty_meta(node, bp->b_lblkno, force);
128151497Sru	if (error)
129151497Sru		nandfs_error("%s: cannot dirty buffer %p\n",
130151497Sru		    __func__, bp);
131151497Sru
132151497Sru	return (error);
133151497Sru}
134151497Sru
135151497Srustatic int
136151497Srunandfs_bmap_update_mapping(struct nandfs_node *node, nandfs_lbn_t lblk,
137151497Sru    nandfs_daddr_t blknr)
138151497Sru{
139151497Sru	int error;
140151497Sru
141151497Sru	DPRINTF(BMAP,
142151497Sru	    ("%s: node: %p ino: %#jx lblk: %#jx vblk: %#jx\n",
143151497Sru	    __func__, node, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
144151497Sru	    (uintmax_t)blknr));
145151497Sru
146151497Sru	error = bmap_insert_block(node, lblk, blknr);
147151497Sru
148151497Sru	return (error);
149151497Sru}
150151497Sru
151151497Sruint
152151497Srunandfs_bmap_update_block(struct nandfs_node *node, struct buf *bp,
153151497Sru    nandfs_lbn_t blknr)
154151497Sru{
155151497Sru	nandfs_lbn_t lblk;
156151497Sru	int error;
157151497Sru
158151497Sru	lblk = bp->b_lblkno;
159151497Sru	nandfs_vblk_set(bp, blknr);
160151497Sru
161151497Sru	DPRINTF(BMAP, ("%s: node: %p ino: %#jx bp: %p lblk: %#jx blk: %#jx\n",
162151497Sru	    __func__, node, (uintmax_t)node->nn_ino, bp,
163151497Sru	    (uintmax_t)lblk, (uintmax_t)blknr));
164151497Sru
165151497Sru	error = nandfs_bmap_update_mapping(node, lblk, blknr);
166151497Sru	if (error) {
167151497Sru		nandfs_error("%s: cannot update lblk:%jx to blk:%jx for "
168151497Sru		    "node:%p, error:%d\n", __func__, (uintmax_t)lblk,
169151497Sru		    (uintmax_t)blknr, node, error);
170151497Sru		return (error);
171151497Sru	}
172151497Sru
173151497Sru	return (error);
174151497Sru}
175151497Sru
176151497Sruint
177151497Srunandfs_bmap_update_dat(struct nandfs_node *node, nandfs_daddr_t oldblk,
178151497Sru    struct buf *bp)
179151497Sru{
180151497Sru	struct nandfs_device *fsdev;
181151497Sru	nandfs_daddr_t vblk = 0;
182151497Sru	int error;
183151497Sru
184151497Sru	if (node->nn_ino == NANDFS_DAT_INO)
185151497Sru		return (0);
186151497Sru
187151497Sru	if (nandfs_buf_check(bp, NANDFS_VBLK_ASSIGNED)) {
188151497Sru		nandfs_buf_clear(bp, NANDFS_VBLK_ASSIGNED);
189151497Sru		return (0);
190151497Sru	}
191151497Sru
192151497Sru	fsdev = node->nn_nandfsdev;
193151497Sru
194151497Sru	/* First alloc new virtual block.... */
195151497Sru	error = nandfs_vblock_alloc(fsdev, &vblk);
196151497Sru	if (error)
197151497Sru		return (error);
198151497Sru
199151497Sru	error = nandfs_bmap_update_block(node, bp, vblk);
200151497Sru	if (error)
201151497Sru		return (error);
202151497Sru
203151497Sru	/* Then we can end up with old one */
204151497Sru	nandfs_vblock_end(fsdev, oldblk);
205151497Sru
206151497Sru	DPRINTF(BMAP,
207151497Sru	    ("%s: ino %#jx block %#jx: update vblk %#jx to %#jx\n",
208151497Sru	    __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno,
209151497Sru	    (uintmax_t)oldblk, (uintmax_t)vblk));
210151497Sru	return (error);
211151497Sru}
212151497Sru
213151497Sruint
214151497Srunandfs_bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t oblk,
215151497Sru    nandfs_lbn_t nblk)
216151497Sru{
217151497Sru	nandfs_lbn_t todo;
218151497Sru	int error;
219151497Sru
220151497Sru	todo = oblk - nblk;
221151497Sru
222151497Sru	DPRINTF(BMAP, ("%s: node %p oblk %jx nblk %jx truncate by %jx\n",
223151497Sru	    __func__, node, oblk, nblk, todo));
224151497Sru
225151497Sru	error = bmap_truncate_mapping(node, oblk, todo);
226151497Sru	if (error)
227151497Sru		return (error);
228151497Sru
229151497Sru	return (error);
230151497Sru}
231151497Sru