source: mainline/uspace/srv/fs/minixfs/mfs_dentry.c@ 488f7ed

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 488f7ed was 488f7ed, checked in by Maurizio Lombardi <m.lombardi85@…>, 14 years ago

read_directory_entry() should return an error code, not a poniter to the directory structure

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2011 Maurizio Lombardi
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33#include <assert.h>
34#include <errno.h>
35#include "mfs.h"
36#include "mfs_utils.h"
37
38int
39read_directory_entry(struct mfs_node *mnode,
40 struct mfs_dentry_info **d_info, unsigned index)
41{
42 const struct mfs_instance *inst = mnode->instance;
43 const struct mfs_sb_info *sbi = inst->sbi;
44 const bool longnames = sbi->long_names;
45 uint32_t block;
46 block_t *b;
47
48 mfsdebug("read_directory(%u)\n", index);
49
50 *d_info = malloc(sizeof(**d_info));
51 if (!*d_info)
52 return ENOMEM;
53
54 int r = read_map(&block, mnode, index * sbi->dirsize);
55 if (r != EOK)
56 goto out_err;
57
58 if (block == 0) {
59 r = EIO;
60 goto out_err;
61 }
62
63 r = block_get(&b, inst->handle, block, BLOCK_FLAGS_NONE);
64 if (r != EOK)
65 goto out_err;
66
67 unsigned dentries_per_zone = sbi->block_size / sbi->dirsize;
68 unsigned dentry_off = index % (dentries_per_zone - 1);
69
70 if (sbi->fs_version == MFS_VERSION_V3) {
71 struct mfs3_dentry *d3;
72
73 d3 = b->data + (dentry_off * MFS3_DIRSIZE);
74
75 (*d_info)->d_inum = conv32(sbi->native, d3->d_inum);
76 memcpy((*d_info)->d_name, d3->d_name, MFS3_MAX_NAME_LEN);
77 } else {
78 const int namelen = longnames ? MFS_L_MAX_NAME_LEN :
79 MFS_MAX_NAME_LEN;
80
81 struct mfs_dentry *d;
82
83 d = b->data + dentry_off * (longnames ? MFSL_DIRSIZE :
84 MFS_DIRSIZE);
85 (*d_info)->d_inum = conv16(sbi->native, d->d_inum);
86 memcpy((*d_info)->d_name, d->d_name, namelen);
87 }
88
89 block_put(b);
90
91 (*d_info)->index = index;
92 (*d_info)->node = mnode;
93 return EOK;
94
95out_err:
96 free(*d_info);
97 *d_info = NULL;
98 return r;
99}
100
101int
102write_dentry(struct mfs_dentry_info *d_info)
103{
104 struct mfs_node *mnode = d_info->node;
105 struct mfs_sb_info *sbi = mnode->instance->sbi;
106 const unsigned d_off_bytes = d_info->index * sbi->dirsize;
107 const unsigned dirs_per_block = sbi->block_size / sbi->dirsize;
108 block_t *b;
109 uint32_t block;
110 int r;
111
112 r = read_map(&block, mnode, d_off_bytes);
113 if (r != EOK)
114 goto out;
115
116 r = block_get(&b, mnode->instance->handle, block, BLOCK_FLAGS_NONE);
117 if (r != EOK)
118 goto out;
119
120 const size_t name_len = sbi->max_name_len;
121 uint8_t *ptr = b->data;
122 ptr += (d_info->index % dirs_per_block) * sbi->dirsize;
123
124 if (sbi->fs_version == MFS_VERSION_V3) {
125 struct mfs3_dentry *dentry;
126 dentry = (struct mfs3_dentry *) ptr;
127
128 dentry->d_inum = conv32(sbi->native, d_info->d_inum);
129 memcpy(dentry->d_name, d_info->d_name, name_len);
130 } else {
131 struct mfs_dentry *dentry;
132 dentry = (struct mfs_dentry *) ptr;
133
134 dentry->d_inum = conv16(sbi->native, d_info->d_inum);
135 memcpy(dentry->d_name, d_info->d_name, name_len);
136 }
137
138 b->dirty = true;
139 block_put(b);
140
141out:
142 return r;
143}
144
145int
146insert_dentry(struct mfs_node *mnode, const char *d_name, fs_index_t d_inum)
147{
148 int i, r;
149 struct mfs_sb_info *sbi = mnode->instance->sbi;
150 struct mfs_dentry_info *d_info;
151 bool empty_dentry_found = false;
152
153 const size_t name_len = str_size(d_name);
154
155 assert(name_len <= sbi->max_name_len);
156
157 /*Search for an empty dentry*/
158
159 for (i = 2; ; ++i) {
160 r = read_directory_entry(mnode, &d_info, i);
161 if (r != EOK)
162 return r;
163
164 if (!d_info) {
165 /*Reached the end of the dentries list*/
166 break;
167 }
168
169 if (d_info->d_inum == 0) {
170 /*This entry is not used*/
171 empty_dentry_found = true;
172 break;
173 }
174 free(d_info);
175 }
176
177 if (!empty_dentry_found) {
178 r = inode_grow(mnode, sbi->dirsize);
179 if (r != EOK)
180 return r;
181
182 r = read_directory_entry(mnode, &d_info, i);
183 if (r != EOK)
184 return r;
185 }
186
187 d_info->d_inum = d_inum;
188 memcpy(d_info->d_name, d_name, name_len);
189 d_info->d_name[name_len] = 0;
190
191 return write_dentry(d_info);
192}
193
194
195/**
196 * @}
197 */
198
Note: See TracBrowser for help on using the repository browser.