Skip to content

Commit a464152

Browse files
Russell KingAl Viro
authored andcommitted
fs/adfs: bigdir: implement directory update support
Implement big directory entry update support in the same way that we do for new directories. Signed-off-by: Russell King <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent d79288b commit a464152

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

fs/adfs/dir_fplus.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int adfs_fplus_read(struct super_block *sb, u32 indaddr,
120120
}
121121

122122
dirsize = le32_to_cpu(h->bigdirsize);
123-
if (dirsize != size) {
123+
if (size && dirsize != size) {
124124
adfs_msg(sb, KERN_WARNING,
125125
"dir %06x header size %X does not match directory size %X",
126126
indaddr, dirsize, size);
@@ -226,9 +226,61 @@ static int adfs_fplus_iterate(struct adfs_dir *dir, struct dir_context *ctx)
226226
return 0;
227227
}
228228

229+
static int adfs_fplus_update(struct adfs_dir *dir, struct object_info *obj)
230+
{
231+
struct adfs_bigdirheader *h = dir->bighead;
232+
struct adfs_bigdirentry bde;
233+
int offset, end, ret;
234+
235+
offset = adfs_fplus_offset(h, 0) - sizeof(bde);
236+
end = adfs_fplus_offset(h, le32_to_cpu(h->bigdirentries));
237+
238+
do {
239+
offset += sizeof(bde);
240+
if (offset >= end) {
241+
adfs_error(dir->sb, "unable to locate entry to update");
242+
return -ENOENT;
243+
}
244+
ret = adfs_dir_copyfrom(&bde, dir, offset, sizeof(bde));
245+
if (ret) {
246+
adfs_error(dir->sb, "error reading directory entry");
247+
return -ENOENT;
248+
}
249+
} while (le32_to_cpu(bde.bigdirindaddr) != obj->indaddr);
250+
251+
bde.bigdirload = cpu_to_le32(obj->loadaddr);
252+
bde.bigdirexec = cpu_to_le32(obj->execaddr);
253+
bde.bigdirlen = cpu_to_le32(obj->size);
254+
bde.bigdirindaddr = cpu_to_le32(obj->indaddr);
255+
bde.bigdirattr = cpu_to_le32(obj->attr);
256+
257+
return adfs_dir_copyto(dir, offset, &bde, sizeof(bde));
258+
}
259+
260+
static int adfs_fplus_commit(struct adfs_dir *dir)
261+
{
262+
int ret;
263+
264+
/* Increment directory sequence number */
265+
dir->bighead->startmasseq += 1;
266+
dir->bigtail->bigdirendmasseq += 1;
267+
268+
/* Update directory check byte */
269+
dir->bigtail->bigdircheckbyte = adfs_fplus_checkbyte(dir);
270+
271+
/* Make sure the directory still validates correctly */
272+
ret = adfs_fplus_validate_header(dir->bighead);
273+
if (ret == 0)
274+
ret = adfs_fplus_validate_tail(dir->bighead, dir->bigtail);
275+
276+
return ret;
277+
}
278+
229279
const struct adfs_dir_ops adfs_fplus_dir_ops = {
230280
.read = adfs_fplus_read,
231281
.iterate = adfs_fplus_iterate,
232282
.setpos = adfs_fplus_setpos,
233283
.getnext = adfs_fplus_getnext,
284+
.update = adfs_fplus_update,
285+
.commit = adfs_fplus_commit,
234286
};

0 commit comments

Comments
 (0)