xref: /inferno-os/libnandfs/writeblock.c (revision c094a1409b780cc543c077e8469fdb28b4c90afb)
1 #include "lib9.h"
2 #include "logfs.h"
3 #include "nandfs.h"
4 #include "local.h"
5 
6 char *
7 nandfswriteblock(Nandfs *nandfs, void *buf, uchar tag, ulong path, int xcount, long *data, long block)
8 {
9 	int p;
10 	char *errmsg;
11 
12 	ulong opath = nandfsgetpath(nandfs, block);
13 	ulong writepath = (~opath | path) & NandfsPathMask;
14 	uchar writetag = ~nandfsgettag(nandfs, block) | tag;
15 	int ppb = 1 << nandfs->ll.l2pagesperblock;
16 
17 	for (p = 0; p < ppb; p++) {
18 		ulong wp;
19 		if (p > 0 && p <= 2 + xcount) {
20 			switch (p) {
21 			case 1:
22 				wp = (~opath | nandfsgetbaseblock(nandfs)) & NandfsPathMask;
23 				break;
24 			case 2:
25 				wp = (~opath | nandfs->ll.blocks) & NandfsPathMask;
26 				break;
27 			default:
28 				wp = (~opath | data[p - 3]) & NandfsPathMask;
29 				break;
30 			}
31 		}
32 		else
33 			wp = writepath;
34 		errmsg = nandfsupdatepage(nandfs, buf, wp, writetag, block, p);
35 		if (errmsg)
36 			return errmsg;
37 #ifdef LOGFSTEST
38 		if (logfstest.partialupdate && p > 0) {
39 			print("skipping pageupdate\n");
40 			break;
41 		}
42 #endif
43 		buf = (uchar *)buf + NandfsPageSize;
44 	}
45 
46 	return nil;
47 }
48