1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/fs/hpfs/ea.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * handling extended attributes
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include "hpfs_fn.h"
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun /* Remove external extended attributes. ano specifies whether a is a
13*4882a593Smuzhiyun direct sector where eas starts or an anode */
14*4882a593Smuzhiyun
hpfs_ea_ext_remove(struct super_block * s,secno a,int ano,unsigned len)15*4882a593Smuzhiyun void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun unsigned pos = 0;
18*4882a593Smuzhiyun while (pos < len) {
19*4882a593Smuzhiyun char ex[4 + 255 + 1 + 8];
20*4882a593Smuzhiyun struct extended_attribute *ea = (struct extended_attribute *)ex;
21*4882a593Smuzhiyun if (pos + 4 > len) {
22*4882a593Smuzhiyun hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
23*4882a593Smuzhiyun ano ? "anode" : "sectors", a, len);
24*4882a593Smuzhiyun return;
25*4882a593Smuzhiyun }
26*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
27*4882a593Smuzhiyun if (ea_indirect(ea)) {
28*4882a593Smuzhiyun if (ea_valuelen(ea) != 8) {
29*4882a593Smuzhiyun hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
30*4882a593Smuzhiyun ano ? "anode" : "sectors", a, pos);
31*4882a593Smuzhiyun return;
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
34*4882a593Smuzhiyun return;
35*4882a593Smuzhiyun hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun pos += ea->namelen + ea_valuelen(ea) + 5;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
40*4882a593Smuzhiyun else {
41*4882a593Smuzhiyun struct buffer_head *bh;
42*4882a593Smuzhiyun struct anode *anode;
43*4882a593Smuzhiyun if ((anode = hpfs_map_anode(s, a, &bh))) {
44*4882a593Smuzhiyun hpfs_remove_btree(s, &anode->btree);
45*4882a593Smuzhiyun brelse(bh);
46*4882a593Smuzhiyun hpfs_free_sectors(s, a, 1);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
get_indirect_ea(struct super_block * s,int ano,secno a,int size)51*4882a593Smuzhiyun static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun char *ret;
54*4882a593Smuzhiyun if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
55*4882a593Smuzhiyun pr_err("out of memory for EA\n");
56*4882a593Smuzhiyun return NULL;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
59*4882a593Smuzhiyun kfree(ret);
60*4882a593Smuzhiyun return NULL;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun ret[size] = 0;
63*4882a593Smuzhiyun return ret;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
set_indirect_ea(struct super_block * s,int ano,secno a,const char * data,int size)66*4882a593Smuzhiyun static void set_indirect_ea(struct super_block *s, int ano, secno a,
67*4882a593Smuzhiyun const char *data, int size)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun hpfs_ea_write(s, a, ano, 0, size, data);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* Read an extended attribute named 'key' into the provided buffer */
73*4882a593Smuzhiyun
hpfs_read_ea(struct super_block * s,struct fnode * fnode,char * key,char * buf,int size)74*4882a593Smuzhiyun int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
75*4882a593Smuzhiyun char *buf, int size)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun unsigned pos;
78*4882a593Smuzhiyun int ano, len;
79*4882a593Smuzhiyun secno a;
80*4882a593Smuzhiyun char ex[4 + 255 + 1 + 8];
81*4882a593Smuzhiyun struct extended_attribute *ea;
82*4882a593Smuzhiyun struct extended_attribute *ea_end = fnode_end_ea(fnode);
83*4882a593Smuzhiyun for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
84*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
85*4882a593Smuzhiyun if (ea_indirect(ea))
86*4882a593Smuzhiyun goto indirect;
87*4882a593Smuzhiyun if (ea_valuelen(ea) >= size)
88*4882a593Smuzhiyun return -EINVAL;
89*4882a593Smuzhiyun memcpy(buf, ea_data(ea), ea_valuelen(ea));
90*4882a593Smuzhiyun buf[ea_valuelen(ea)] = 0;
91*4882a593Smuzhiyun return 0;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun a = le32_to_cpu(fnode->ea_secno);
94*4882a593Smuzhiyun len = le32_to_cpu(fnode->ea_size_l);
95*4882a593Smuzhiyun ano = fnode_in_anode(fnode);
96*4882a593Smuzhiyun pos = 0;
97*4882a593Smuzhiyun while (pos < len) {
98*4882a593Smuzhiyun ea = (struct extended_attribute *)ex;
99*4882a593Smuzhiyun if (pos + 4 > len) {
100*4882a593Smuzhiyun hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
101*4882a593Smuzhiyun ano ? "anode" : "sectors", a, len);
102*4882a593Smuzhiyun return -EIO;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
105*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
106*4882a593Smuzhiyun return -EIO;
107*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
108*4882a593Smuzhiyun if (ea_indirect(ea))
109*4882a593Smuzhiyun goto indirect;
110*4882a593Smuzhiyun if (ea_valuelen(ea) >= size)
111*4882a593Smuzhiyun return -EINVAL;
112*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
113*4882a593Smuzhiyun return -EIO;
114*4882a593Smuzhiyun buf[ea_valuelen(ea)] = 0;
115*4882a593Smuzhiyun return 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun pos += ea->namelen + ea_valuelen(ea) + 5;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun return -ENOENT;
120*4882a593Smuzhiyun indirect:
121*4882a593Smuzhiyun if (ea_len(ea) >= size)
122*4882a593Smuzhiyun return -EINVAL;
123*4882a593Smuzhiyun if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
124*4882a593Smuzhiyun return -EIO;
125*4882a593Smuzhiyun buf[ea_len(ea)] = 0;
126*4882a593Smuzhiyun return 0;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /* Read an extended attribute named 'key' */
hpfs_get_ea(struct super_block * s,struct fnode * fnode,char * key,int * size)130*4882a593Smuzhiyun char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun char *ret;
133*4882a593Smuzhiyun unsigned pos;
134*4882a593Smuzhiyun int ano, len;
135*4882a593Smuzhiyun secno a;
136*4882a593Smuzhiyun struct extended_attribute *ea;
137*4882a593Smuzhiyun struct extended_attribute *ea_end = fnode_end_ea(fnode);
138*4882a593Smuzhiyun for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
139*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
140*4882a593Smuzhiyun if (ea_indirect(ea))
141*4882a593Smuzhiyun return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
142*4882a593Smuzhiyun if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
143*4882a593Smuzhiyun pr_err("out of memory for EA\n");
144*4882a593Smuzhiyun return NULL;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun memcpy(ret, ea_data(ea), ea_valuelen(ea));
147*4882a593Smuzhiyun ret[ea_valuelen(ea)] = 0;
148*4882a593Smuzhiyun return ret;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun a = le32_to_cpu(fnode->ea_secno);
151*4882a593Smuzhiyun len = le32_to_cpu(fnode->ea_size_l);
152*4882a593Smuzhiyun ano = fnode_in_anode(fnode);
153*4882a593Smuzhiyun pos = 0;
154*4882a593Smuzhiyun while (pos < len) {
155*4882a593Smuzhiyun char ex[4 + 255 + 1 + 8];
156*4882a593Smuzhiyun ea = (struct extended_attribute *)ex;
157*4882a593Smuzhiyun if (pos + 4 > len) {
158*4882a593Smuzhiyun hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
159*4882a593Smuzhiyun ano ? "anode" : "sectors", a, len);
160*4882a593Smuzhiyun return NULL;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
163*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
164*4882a593Smuzhiyun return NULL;
165*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
166*4882a593Smuzhiyun if (ea_indirect(ea))
167*4882a593Smuzhiyun return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
168*4882a593Smuzhiyun if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
169*4882a593Smuzhiyun pr_err("out of memory for EA\n");
170*4882a593Smuzhiyun return NULL;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
173*4882a593Smuzhiyun kfree(ret);
174*4882a593Smuzhiyun return NULL;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun ret[ea_valuelen(ea)] = 0;
177*4882a593Smuzhiyun return ret;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun pos += ea->namelen + ea_valuelen(ea) + 5;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun return NULL;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /*
185*4882a593Smuzhiyun * Update or create extended attribute 'key' with value 'data'. Note that
186*4882a593Smuzhiyun * when this ea exists, it MUST have the same size as size of data.
187*4882a593Smuzhiyun * This driver can't change sizes of eas ('cause I just don't need it).
188*4882a593Smuzhiyun */
189*4882a593Smuzhiyun
hpfs_set_ea(struct inode * inode,struct fnode * fnode,const char * key,const char * data,int size)190*4882a593Smuzhiyun void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
191*4882a593Smuzhiyun const char *data, int size)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun fnode_secno fno = inode->i_ino;
194*4882a593Smuzhiyun struct super_block *s = inode->i_sb;
195*4882a593Smuzhiyun unsigned pos;
196*4882a593Smuzhiyun int ano, len;
197*4882a593Smuzhiyun secno a;
198*4882a593Smuzhiyun unsigned char h[4];
199*4882a593Smuzhiyun struct extended_attribute *ea;
200*4882a593Smuzhiyun struct extended_attribute *ea_end = fnode_end_ea(fnode);
201*4882a593Smuzhiyun for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
202*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
203*4882a593Smuzhiyun if (ea_indirect(ea)) {
204*4882a593Smuzhiyun if (ea_len(ea) == size)
205*4882a593Smuzhiyun set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
206*4882a593Smuzhiyun } else if (ea_valuelen(ea) == size) {
207*4882a593Smuzhiyun memcpy(ea_data(ea), data, size);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun return;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun a = le32_to_cpu(fnode->ea_secno);
212*4882a593Smuzhiyun len = le32_to_cpu(fnode->ea_size_l);
213*4882a593Smuzhiyun ano = fnode_in_anode(fnode);
214*4882a593Smuzhiyun pos = 0;
215*4882a593Smuzhiyun while (pos < len) {
216*4882a593Smuzhiyun char ex[4 + 255 + 1 + 8];
217*4882a593Smuzhiyun ea = (struct extended_attribute *)ex;
218*4882a593Smuzhiyun if (pos + 4 > len) {
219*4882a593Smuzhiyun hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
220*4882a593Smuzhiyun ano ? "anode" : "sectors", a, len);
221*4882a593Smuzhiyun return;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
224*4882a593Smuzhiyun if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
225*4882a593Smuzhiyun return;
226*4882a593Smuzhiyun if (!strcmp(ea->name, key)) {
227*4882a593Smuzhiyun if (ea_indirect(ea)) {
228*4882a593Smuzhiyun if (ea_len(ea) == size)
229*4882a593Smuzhiyun set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun else {
232*4882a593Smuzhiyun if (ea_valuelen(ea) == size)
233*4882a593Smuzhiyun hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun return;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun pos += ea->namelen + ea_valuelen(ea) + 5;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun if (!le16_to_cpu(fnode->ea_offs)) {
240*4882a593Smuzhiyun /*if (le16_to_cpu(fnode->ea_size_s)) {
241*4882a593Smuzhiyun hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
242*4882a593Smuzhiyun inode->i_ino, le16_to_cpu(fnode->ea_size_s));
243*4882a593Smuzhiyun return;
244*4882a593Smuzhiyun }*/
245*4882a593Smuzhiyun fnode->ea_offs = cpu_to_le16(0xc4);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) {
248*4882a593Smuzhiyun hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
249*4882a593Smuzhiyun (unsigned long)inode->i_ino,
250*4882a593Smuzhiyun le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
251*4882a593Smuzhiyun return;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
254*4882a593Smuzhiyun le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5 <= 0x200) {
255*4882a593Smuzhiyun ea = fnode_end_ea(fnode);
256*4882a593Smuzhiyun *(char *)ea = 0;
257*4882a593Smuzhiyun ea->namelen = strlen(key);
258*4882a593Smuzhiyun ea->valuelen_lo = size;
259*4882a593Smuzhiyun ea->valuelen_hi = size >> 8;
260*4882a593Smuzhiyun strcpy(ea->name, key);
261*4882a593Smuzhiyun memcpy(ea_data(ea), data, size);
262*4882a593Smuzhiyun fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
263*4882a593Smuzhiyun goto ret;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun /* Most the code here is 99.9993422% unused. I hope there are no bugs.
266*4882a593Smuzhiyun But what .. HPFS.IFS has also bugs in ea management. */
267*4882a593Smuzhiyun if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
268*4882a593Smuzhiyun secno n;
269*4882a593Smuzhiyun struct buffer_head *bh;
270*4882a593Smuzhiyun char *data;
271*4882a593Smuzhiyun if (!(n = hpfs_alloc_sector(s, fno, 1, 0))) return;
272*4882a593Smuzhiyun if (!(data = hpfs_get_sector(s, n, &bh))) {
273*4882a593Smuzhiyun hpfs_free_sectors(s, n, 1);
274*4882a593Smuzhiyun return;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
277*4882a593Smuzhiyun fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
278*4882a593Smuzhiyun fnode->ea_size_s = cpu_to_le16(0);
279*4882a593Smuzhiyun fnode->ea_secno = cpu_to_le32(n);
280*4882a593Smuzhiyun fnode->flags &= ~FNODE_anode;
281*4882a593Smuzhiyun mark_buffer_dirty(bh);
282*4882a593Smuzhiyun brelse(bh);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
285*4882a593Smuzhiyun len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
286*4882a593Smuzhiyun if (pos >= 30000) goto bail;
287*4882a593Smuzhiyun while (((pos + 511) >> 9) > len) {
288*4882a593Smuzhiyun if (!len) {
289*4882a593Smuzhiyun secno q = hpfs_alloc_sector(s, fno, 1, 0);
290*4882a593Smuzhiyun if (!q) goto bail;
291*4882a593Smuzhiyun fnode->ea_secno = cpu_to_le32(q);
292*4882a593Smuzhiyun fnode->flags &= ~FNODE_anode;
293*4882a593Smuzhiyun len++;
294*4882a593Smuzhiyun } else if (!fnode_in_anode(fnode)) {
295*4882a593Smuzhiyun if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
296*4882a593Smuzhiyun len++;
297*4882a593Smuzhiyun } else {
298*4882a593Smuzhiyun /* Aargh... don't know how to create ea anodes :-( */
299*4882a593Smuzhiyun /*struct buffer_head *bh;
300*4882a593Smuzhiyun struct anode *anode;
301*4882a593Smuzhiyun anode_secno a_s;
302*4882a593Smuzhiyun if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
303*4882a593Smuzhiyun goto bail;
304*4882a593Smuzhiyun anode->up = cpu_to_le32(fno);
305*4882a593Smuzhiyun anode->btree.fnode_parent = 1;
306*4882a593Smuzhiyun anode->btree.n_free_nodes--;
307*4882a593Smuzhiyun anode->btree.n_used_nodes++;
308*4882a593Smuzhiyun anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
309*4882a593Smuzhiyun anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
310*4882a593Smuzhiyun anode->u.external[0].file_secno = cpu_to_le32(0);
311*4882a593Smuzhiyun anode->u.external[0].length = cpu_to_le32(len);
312*4882a593Smuzhiyun mark_buffer_dirty(bh);
313*4882a593Smuzhiyun brelse(bh);
314*4882a593Smuzhiyun fnode->flags |= FNODE_anode;
315*4882a593Smuzhiyun fnode->ea_secno = cpu_to_le32(a_s);*/
316*4882a593Smuzhiyun secno new_sec;
317*4882a593Smuzhiyun int i;
318*4882a593Smuzhiyun if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
319*4882a593Smuzhiyun goto bail;
320*4882a593Smuzhiyun for (i = 0; i < len; i++) {
321*4882a593Smuzhiyun struct buffer_head *bh1, *bh2;
322*4882a593Smuzhiyun void *b1, *b2;
323*4882a593Smuzhiyun if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
324*4882a593Smuzhiyun hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
325*4882a593Smuzhiyun goto bail;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
328*4882a593Smuzhiyun brelse(bh1);
329*4882a593Smuzhiyun hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
330*4882a593Smuzhiyun goto bail;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun memcpy(b2, b1, 512);
333*4882a593Smuzhiyun brelse(bh1);
334*4882a593Smuzhiyun mark_buffer_dirty(bh2);
335*4882a593Smuzhiyun brelse(bh2);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
338*4882a593Smuzhiyun fnode->ea_secno = cpu_to_le32(new_sec);
339*4882a593Smuzhiyun len = (pos + 511) >> 9;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun if (fnode_in_anode(fnode)) {
343*4882a593Smuzhiyun if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
344*4882a593Smuzhiyun 0, len) != -1) {
345*4882a593Smuzhiyun len++;
346*4882a593Smuzhiyun } else {
347*4882a593Smuzhiyun goto bail;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun h[0] = 0;
352*4882a593Smuzhiyun h[1] = strlen(key);
353*4882a593Smuzhiyun h[2] = size & 0xff;
354*4882a593Smuzhiyun h[3] = size >> 8;
355*4882a593Smuzhiyun if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
356*4882a593Smuzhiyun if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
357*4882a593Smuzhiyun if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
358*4882a593Smuzhiyun fnode->ea_size_l = cpu_to_le32(pos);
359*4882a593Smuzhiyun ret:
360*4882a593Smuzhiyun hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
361*4882a593Smuzhiyun return;
362*4882a593Smuzhiyun bail:
363*4882a593Smuzhiyun if (le32_to_cpu(fnode->ea_secno))
364*4882a593Smuzhiyun if (fnode_in_anode(fnode)) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
365*4882a593Smuzhiyun else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9));
366*4882a593Smuzhiyun else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
369