1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010-2012 Semihalf.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/conf.h>
35 #include <sys/kernel.h>
36 #include <sys/lock.h>
37 #include <sys/malloc.h>
38 #include <sys/mount.h>
39 #include <sys/mutex.h>
40 #include <sys/namei.h>
41 #include <sys/sysctl.h>
42 #include <sys/vnode.h>
43 #include <sys/buf.h>
44 #include <sys/bio.h>
45
46 #include <vm/vm.h>
47 #include <vm/vm_param.h>
48 #include <vm/vm_kern.h>
49 #include <vm/vm_page.h>
50
51 #include <fs/nandfs/nandfs_mount.h>
52 #include <fs/nandfs/nandfs.h>
53 #include <fs/nandfs/nandfs_subr.h>
54
55 int
56 nandfs_node_create(struct nandfsmount *nmp, struct nandfs_node **node,
57 uint16_t mode)
58 {
59 struct nandfs_alloc_request req;
60 struct nandfs_device *nandfsdev;
61 struct nandfs_mdt *mdt;
62 struct nandfs_node *ifile;
63 struct nandfs_inode *inode;
64 struct vnode *vp;
65 uint32_t entry;
66 int error = 0;
67
68 nandfsdev = nmp->nm_nandfsdev;
69 mdt = &nandfsdev->nd_ifile_mdt;
70 ifile = nmp->nm_ifile_node;
71 vp = NTOV(ifile);
72
73 VOP_LOCK(vp, LK_EXCLUSIVE);
74 /* Allocate new inode in ifile */
75 req.entrynum = nandfsdev->nd_last_ino + 1;
76 error = nandfs_find_free_entry(mdt, ifile, &req);
77 if (error) {
78 VOP_UNLOCK(vp, 0);
79 return (error);
80 }
81
82 error = nandfs_get_entry_block(mdt, ifile, &req, &entry, 1);
83 if (error) {
84 VOP_UNLOCK(vp, 0);
85 return (error);
86 }
87
88 /* Inode initialization */
89 inode = ((struct nandfs_inode *) req.bp_entry->b_data) + entry;
90 nandfs_inode_init(inode, mode);
91
92 error = nandfs_alloc_entry(mdt, &req);
93 if (error) {
94 VOP_UNLOCK(vp, 0);
95 return (error);
96 }
97
98 VOP_UNLOCK(vp, 0);
99
100 nandfsdev->nd_last_ino = req.entrynum;
101 error = nandfs_get_node(nmp, req.entrynum, node);
102 DPRINTF(IFILE, ("%s: node: %p ino: %#jx\n",
103 __func__, node, (uintmax_t)((*node)->nn_ino)));
104
105 return (error);
106 }
107
108 int
109 nandfs_node_destroy(struct nandfs_node *node)
110 {
111 struct nandfs_alloc_request req;
112 struct nandfsmount *nmp;
113 struct nandfs_mdt *mdt;
114 struct nandfs_node *ifile;
115 struct vnode *vp;
116 int error = 0;
117
118 nmp = node->nn_nmp;
119 req.entrynum = node->nn_ino;
120 mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
121 ifile = nmp->nm_ifile_node;
122 vp = NTOV(ifile);
123
124 DPRINTF(IFILE, ("%s: destroy node: %p ino: %#jx\n",
125 __func__, node, (uintmax_t)node->nn_ino));
126 VOP_LOCK(vp, LK_EXCLUSIVE);
127
128 error = nandfs_find_entry(mdt, ifile, &req);
129 if (error) {
130 nandfs_error("%s: finding entry error:%d node %p(%jx)",
131 __func__, error, node, node->nn_ino);
132 VOP_UNLOCK(vp, 0);
133 return (error);
134 }
135
136 nandfs_inode_destroy(&node->nn_inode);
137
138 error = nandfs_free_entry(mdt, &req);
139 if (error) {
140 nandfs_error("%s: freing entry error:%d node %p(%jx)",
141 __func__, error, node, node->nn_ino);
142 VOP_UNLOCK(vp, 0);
143 return (error);
144 }
145
146 VOP_UNLOCK(vp, 0);
147 DPRINTF(IFILE, ("%s: freed node %p ino %#jx\n",
148 __func__, node, (uintmax_t)node->nn_ino));
149 return (error);
150 }
151
152 int
153 nandfs_node_update(struct nandfs_node *node)
154 {
155 struct nandfs_alloc_request req;
156 struct nandfsmount *nmp;
157 struct nandfs_mdt *mdt;
158 struct nandfs_node *ifile;
159 struct nandfs_inode *inode;
160 uint32_t index;
161 int error = 0;
162
163 nmp = node->nn_nmp;
164 ifile = nmp->nm_ifile_node;
165 ASSERT_VOP_LOCKED(NTOV(ifile), __func__);
166
167 req.entrynum = node->nn_ino;
168 mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
169
170 DPRINTF(IFILE, ("%s: node:%p ino:%#jx\n",
171 __func__, &node->nn_inode, (uintmax_t)node->nn_ino));
172
173 error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0);
174 if (error) {
175 printf("nandfs_get_entry_block returned with ERROR=%d\n",
176 error);
177 return (error);
178 }
179
180 inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index;
181 memcpy(inode, &node->nn_inode, sizeof(*inode));
182 error = nandfs_dirty_buf(req.bp_entry, 0);
183
184 return (error);
185 }
186
187 int
188 nandfs_get_node_entry(struct nandfsmount *nmp, struct nandfs_inode **inode,
189 uint64_t ino, struct buf **bp)
190 {
191 struct nandfs_alloc_request req;
192 struct nandfs_mdt *mdt;
193 struct nandfs_node *ifile;
194 struct vnode *vp;
195 uint32_t index;
196 int error = 0;
197
198 req.entrynum = ino;
199 mdt = &nmp->nm_nandfsdev->nd_ifile_mdt;
200 ifile = nmp->nm_ifile_node;
201 vp = NTOV(ifile);
202
203 VOP_LOCK(vp, LK_EXCLUSIVE);
204 error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0);
205 if (error) {
206 VOP_UNLOCK(vp, 0);
207 return (error);
208 }
209
210 *inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index;
211 *bp = req.bp_entry;
212 VOP_UNLOCK(vp, 0);
213 return (0);
214 }
215
Cache object: 40692be1b8c58ca5210c9447d4ee4201
|