]> git.proxmox.com Git - mirror_zfs-debian.git/blame - zfs/lib/libudmu/udmu_util.c
Remove stray stub kernel files which should be brought in my linux-kernel-module...
[mirror_zfs-debian.git] / zfs / lib / libudmu / udmu_util.c
CommitLineData
34dc7c2f
BB
1/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
3 *
4 * lustre/dmu/udmu.c
5 * Module that interacts with the ZFS DMU and provides an abstraction
6 * to the rest of Lustre.
7 *
8 * Copyright (c) 2007 Cluster File Systems, Inc.
9 * Author: Manoj Joseph <manoj.joseph@sun.com>
10 *
11 * This file is part of the Lustre file system, http://www.lustre.org
12 * Lustre is a trademark of Cluster File Systems, Inc.
13 *
14 * You may have signed or agreed to another license before downloading
15 * this software. If so, you are bound by the terms and conditions
16 * of that agreement, and the following does not apply to you. See the
17 * LICENSE file included with this distribution for more information.
18 *
19 * If you did not agree to a different license, then this copy of Lustre
20 * is open source software; you can redistribute it and/or modify it
21 * under the terms of version 2 of the GNU General Public License as
22 * published by the Free Software Foundation.
23 *
24 * In either case, Lustre is distributed in the hope that it will be
25 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
26 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * license text for more details.
28 */
29
30#include <stdio.h>
31#include <string.h>
32#include <errno.h>
33#include <sys/debug.h>
34#include <sys/stat.h>
35#include <sys/statvfs.h>
36#include <sys/errno.h>
37
38#include <udmu.h>
39#include <udmu_util.h>
40
41static int udmu_util_object_delete(udmu_objset_t *uos, dmu_buf_t **dbp,
42 void *tag)
43{
44 dmu_tx_t *tx;
45 uint64_t id;
46 int rc;
47
48 id = udmu_object_get_id(*dbp);
49 tx = udmu_tx_create(uos);
50
51 udmu_tx_hold_free(tx, id, 0, DMU_OBJECT_END);
52
53 rc = udmu_tx_assign(tx, TXG_WAIT);
54 if (rc) {
55 fprintf(stderr,
56 "udmu_util_object_delete: udmu_tx_assign failed (%d)", rc);
57 udmu_tx_abort(tx);
58 return (rc);
59 }
60
61 rc = udmu_object_delete(uos, dbp, tx, tag);
62 if (rc)
63 fprintf(stderr, "udmu_object_delete() failed (%d)", rc);
64
65 udmu_tx_commit(tx);
66 return rc;
67}
68
69int udmu_util_mkdir(udmu_objset_t *uos, dmu_buf_t *parent_db,
70 const char *name, dmu_buf_t **new_dbp, void *tag)
71{
72 dmu_buf_t *db;
73 dmu_tx_t *tx;
74 uint64_t id, pid, value;
75 int rc;
76
77 /* return EEXIST early to avoid object creation/deletion */
78 rc = udmu_zap_lookup(uos, parent_db, name, &id,
79 sizeof(id), sizeof(uint64_t));
80 if (rc == 0)
81 return EEXIST;
82
83 pid = udmu_object_get_id(parent_db);
84
85 tx = udmu_tx_create(uos);
86 udmu_tx_hold_zap(tx, DMU_NEW_OBJECT, 1, NULL); /* for zap create */
87 udmu_tx_hold_bonus(tx, pid); /* for zap_add */
88 udmu_tx_hold_zap(tx, pid, 1, (char *)name); /* for zap_add */
89
90 rc = udmu_tx_assign(tx, TXG_WAIT);
91 if (rc) {
92 fprintf(stderr,
93 "udmu_util_mkdir: udmu_tx_assign failed (%d)", rc);
94 udmu_tx_abort(tx);
95 return (rc);
96 }
97
98 udmu_zap_create(uos, &db, tx, tag);
99 id = udmu_object_get_id(db);
100 value = ZFS_DIRENT_MAKE(0, id);
101 rc = udmu_zap_insert(uos, parent_db, tx, name, &value, sizeof(value));
102 udmu_tx_commit(tx);
103
104 if (rc) {
105 fprintf(stderr, "can't insert (%s) in zap (%d)", name, rc);
106 /* error handling, delete just created object */
107 udmu_util_object_delete(uos, &db, tag);
108 } else if (new_dbp) {
109 *new_dbp = db;
110 } else {
111 udmu_object_put_dmu_buf(db, tag);
112 }
113
114 return (rc);
115}
116
117int udmu_util_setattr(udmu_objset_t *uos, dmu_buf_t *db, vnattr_t *va)
118{
119 dmu_tx_t *tx;
120 int rc;
121
122 tx = udmu_tx_create(uos);
123 udmu_tx_hold_bonus(tx, udmu_object_get_id(db));
124
125 rc = udmu_tx_assign(tx, TXG_WAIT);
126 if (rc) {
127 udmu_tx_abort(tx);
128 } else {
129 udmu_object_setattr(db, tx, va);
130 udmu_tx_commit(tx);
131 }
132
133 return (rc);
134}
135
136int udmu_util_create(udmu_objset_t *uos, dmu_buf_t *parent_db,
137 const char *name, dmu_buf_t **new_dbp, void *tag)
138{
139 dmu_buf_t *db;
140 dmu_tx_t *tx;
141 uint64_t id, pid, value;
142 int rc;
143
144 /* return EEXIST early to avoid object creation/deletion */
145 rc = udmu_zap_lookup(uos, parent_db, name, &id,
146 sizeof(id), sizeof(uint64_t));
147 if (rc == 0)
148 return EEXIST;
149
150 pid = udmu_object_get_id(parent_db);
151
152 tx = udmu_tx_create(uos);
153
154 udmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
155 udmu_tx_hold_bonus(tx, pid);
156 udmu_tx_hold_zap(tx, pid, 1, (char *) name);
157
158 rc = udmu_tx_assign(tx, TXG_WAIT);
159 if (rc) {
160 fprintf(stderr,
161 "udmu_util_create: udmu_tx_assign failed (%d)", rc);
162 udmu_tx_abort(tx);
163 return (rc);
164 }
165
166 udmu_object_create(uos, &db, tx, tag);
167 id = udmu_object_get_id(db);
168 value = ZFS_DIRENT_MAKE(0, id);
169 rc = udmu_zap_insert(uos, parent_db, tx, name,
170 &value, sizeof(value));
171 udmu_tx_commit(tx);
172
173 if (rc) {
174 fprintf(stderr, "can't insert new object in zap (%d)", rc);
175 /* error handling, delete just created object */
176 udmu_util_object_delete(uos, &db, tag);
177 } else if (new_dbp) {
178 *new_dbp = db;
179 } else {
180 udmu_object_put_dmu_buf(db, tag);
181 }
182
183 return (rc);
184}
185
186int udmu_util_lookup(udmu_objset_t *uos, dmu_buf_t *parent_db,
187 const char *name, dmu_buf_t **new_dbp, void *tag)
188{
189 uint64_t id;
190 int rc;
191
192 rc = udmu_zap_lookup(uos, parent_db, name, &id,
193 sizeof(id), sizeof(uint64_t));
194 if (rc == 0) {
195 udmu_object_get_dmu_buf(uos, id, new_dbp, tag);
196 }
197
198 return (rc);
199}
200
201int udmu_util_write(udmu_objset_t *uos, dmu_buf_t *db,
202 uint64_t offset, uint64_t len, void *buf)
203{
204 dmu_tx_t *tx;
205 int set_size = 0;
206 uint64_t end = offset + len;
207 vnattr_t va;
208 int rc;
209
210 udmu_object_getattr(db, &va);
211
212 if (va.va_size < end) {
213 /* extending write; set file size */
214 set_size = 1;
215 va.va_mask = AT_SIZE;
216 va.va_size = end;
217 }
218
219 tx = udmu_tx_create(uos);
220 if (set_size) {
221 udmu_tx_hold_bonus(tx, udmu_object_get_id(db));
222 }
223 udmu_tx_hold_write(tx, udmu_object_get_id(db), offset, len);
224
225 rc = udmu_tx_assign(tx, TXG_WAIT);
226 if (rc) {
227 fprintf(stderr, "dmu_tx_assign() failed %d", rc);
228 udmu_tx_abort(tx);
229 return (-rc);
230 }
231
232 udmu_object_write(uos, db, tx, offset,
233 len, buf);
234 if (set_size) {
235 udmu_object_setattr(db, tx, &va);
236 }
237
238 udmu_tx_commit(tx);
239
240 return (len);
241}