xref: /inferno-os/libnandfs/writeblock.c (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
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