Deleted Added
full compact
ntfs_subr.c (44142) ntfs_subr.c (45879)
1/*-
1/*-
2 * Copyright (c) 1998, 1999 Semen Ustimenko
2 * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
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 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 42 unchanged lines hidden (view full) ---

53
54#if __FreeBSD_version >= 300000
55MALLOC_DEFINE(M_NTFSNTVATTR, "NTFS vattr", "NTFS file attribute information");
56MALLOC_DEFINE(M_NTFSRDATA, "NTFS res data", "NTFS resident data");
57MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage");
58MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary");
59#endif
60
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 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 42 unchanged lines hidden (view full) ---

53
54#if __FreeBSD_version >= 300000
55MALLOC_DEFINE(M_NTFSNTVATTR, "NTFS vattr", "NTFS file attribute information");
56MALLOC_DEFINE(M_NTFSRDATA, "NTFS res data", "NTFS resident data");
57MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage");
58MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary");
59#endif
60
61/*
62 *
63 */
61int
62ntfs_ntvattrrele(
63 struct ntvattr * vap)
64{
65 dprintf(("ntfs_ntvattrrele: ino: %d, type: 0x%x\n",
66 vap->va_ip->i_number, vap->va_type));
67
68 ntfs_ntrele(vap->va_ip);
69
70 return (0);
71}
72
64int
65ntfs_ntvattrrele(
66 struct ntvattr * vap)
67{
68 dprintf(("ntfs_ntvattrrele: ino: %d, type: 0x%x\n",
69 vap->va_ip->i_number, vap->va_type));
70
71 ntfs_ntrele(vap->va_ip);
72
73 return (0);
74}
75
76/*
77 * Search attribute specifed in ntnode (load ntnode if nessecary).
78 * If not found but ATTR_A_ATTRLIST present, read it in and search throught.
79 * VOP_VGET node needed, and lookup througth it's ntnode (load if nessesary).
80 *
81 * ntnode should be locked
82 */
73int
74ntfs_ntvattrget(
75 struct ntfsmount * ntmp,
76 struct ntnode * ip,
77 u_int32_t type,
78 char *name,
79 cn_t vcn,
80 struct ntvattr ** vapp)

--- 27 unchanged lines hidden (view full) ---

108 error = ntfs_loadntnode(ntmp,ip);
109 if(error) {
110 printf("ntfs_ntvattrget: FAILED TO LOAD INO: %d\n",
111 ip->i_number);
112 return (error);
113 }
114 }
115
83int
84ntfs_ntvattrget(
85 struct ntfsmount * ntmp,
86 struct ntnode * ip,
87 u_int32_t type,
88 char *name,
89 cn_t vcn,
90 struct ntvattr ** vapp)

--- 27 unchanged lines hidden (view full) ---

118 error = ntfs_loadntnode(ntmp,ip);
119 if(error) {
120 printf("ntfs_ntvattrget: FAILED TO LOAD INO: %d\n",
121 ip->i_number);
122 return (error);
123 }
124 }
125
116 for (vap = ip->i_vattrp; vap; vap = vap->va_nextp) {
126 for (vap = ip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
117 ddprintf(("type: 0x%x, vcn: %d - %d\n", \
118 vap->va_type, (u_int32_t) vap->va_vcnstart, \
119 (u_int32_t) vap->va_vcnend));
120 if ((vap->va_type == type) &&
121 (vap->va_vcnstart <= vcn) && (vap->va_vcnend >= vcn) &&
122 (vap->va_namelen == namelen) &&
123 (!strncmp(name, vap->va_name, namelen))) {
124 *vapp = vap;

--- 41 unchanged lines hidden (view full) ---

166 (!nextaalp || (nextaalp->al_vcnstart > vcn) ||
167 !AALPCMP(nextaalp, type, name, namelen))) {
168 struct vnode *newvp;
169 struct ntnode *newip;
170
171 dprintf(("ntfs_ntvattrget: attrbute in ino: %d\n",
172 aalp->al_inumber));
173
127 ddprintf(("type: 0x%x, vcn: %d - %d\n", \
128 vap->va_type, (u_int32_t) vap->va_vcnstart, \
129 (u_int32_t) vap->va_vcnend));
130 if ((vap->va_type == type) &&
131 (vap->va_vcnstart <= vcn) && (vap->va_vcnend >= vcn) &&
132 (vap->va_namelen == namelen) &&
133 (!strncmp(name, vap->va_name, namelen))) {
134 *vapp = vap;

--- 41 unchanged lines hidden (view full) ---

176 (!nextaalp || (nextaalp->al_vcnstart > vcn) ||
177 !AALPCMP(nextaalp, type, name, namelen))) {
178 struct vnode *newvp;
179 struct ntnode *newip;
180
181 dprintf(("ntfs_ntvattrget: attrbute in ino: %d\n",
182 aalp->al_inumber));
183
184/*
174 error = VFS_VGET(ntmp->ntm_mountp, aalp->al_inumber,
175 &newvp);
185 error = VFS_VGET(ntmp->ntm_mountp, aalp->al_inumber,
186 &newvp);
187*/
188 error = ntfs_vgetex(ntmp->ntm_mountp, aalp->al_inumber,
189 NTFS_A_DATA, NULL, LK_EXCLUSIVE,
190 VG_EXT, curproc, &newvp);
176 if (error) {
177 printf("ntfs_ntvattrget: CAN'T VGET INO: %d\n",
178 aalp->al_inumber);
179 goto out;
180 }
181 newip = VTONT(newvp);
191 if (error) {
192 printf("ntfs_ntvattrget: CAN'T VGET INO: %d\n",
193 aalp->al_inumber);
194 goto out;
195 }
196 newip = VTONT(newvp);
197 /* XXX have to lock ntnode */
182 if(~newip->i_flag & IN_LOADED) {
183 dprintf(("ntfs_ntvattrget: node not loaded," \
184 " ino: %d\n", newip->i_number));
185 error = ntfs_loadntnode(ntmp,ip);
186 if(error) {
187 printf("ntfs_ntvattrget: CAN'T LOAD " \
188 "INO: %d\n", newip->i_number);
189 vput(newvp);
190 goto out;
191 }
192 }
198 if(~newip->i_flag & IN_LOADED) {
199 dprintf(("ntfs_ntvattrget: node not loaded," \
200 " ino: %d\n", newip->i_number));
201 error = ntfs_loadntnode(ntmp,ip);
202 if(error) {
203 printf("ntfs_ntvattrget: CAN'T LOAD " \
204 "INO: %d\n", newip->i_number);
205 vput(newvp);
206 goto out;
207 }
208 }
193 for (vap = newip->i_vattrp; vap; vap = vap->va_nextp) {
209 for (vap = newip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
194 if ((vap->va_type == type) &&
195 (vap->va_vcnstart <= vcn) &&
196 (vap->va_vcnend >= vcn) &&
197 (vap->va_namelen == namelen) &&
198 (!strncmp(name, vap->va_name, namelen))) {
199 *vapp = vap;
200 ntfs_ntref(vap->va_ip);
201 vput(newvp);

--- 12 unchanged lines hidden (view full) ---

214 }
215 error = ENOENT;
216
217 dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \
218 "ino: %d, type: 0x%x, name: %s, vcn: %d\n", \
219 ip->i_number, type, name, (u_int32_t) vcn));
220out:
221 FREE(alpool, M_TEMP);
210 if ((vap->va_type == type) &&
211 (vap->va_vcnstart <= vcn) &&
212 (vap->va_vcnend >= vcn) &&
213 (vap->va_namelen == namelen) &&
214 (!strncmp(name, vap->va_name, namelen))) {
215 *vapp = vap;
216 ntfs_ntref(vap->va_ip);
217 vput(newvp);

--- 12 unchanged lines hidden (view full) ---

230 }
231 error = ENOENT;
232
233 dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \
234 "ino: %d, type: 0x%x, name: %s, vcn: %d\n", \
235 ip->i_number, type, name, (u_int32_t) vcn));
236out:
237 FREE(alpool, M_TEMP);
222
223 return (error);
224}
225
238 return (error);
239}
240
241/*
242 * Read ntnode from disk, make ntvattr list.
243 *
244 * ntnode should be locked
245 */
226int
227ntfs_loadntnode(
228 struct ntfsmount * ntmp,
229 struct ntnode * ip)
230{
231 struct filerec *mfrp;
232 daddr_t bn;
233 int error,off;
234 struct attr *ap;
246int
247ntfs_loadntnode(
248 struct ntfsmount * ntmp,
249 struct ntnode * ip)
250{
251 struct filerec *mfrp;
252 daddr_t bn;
253 int error,off;
254 struct attr *ap;
235 struct ntvattr**vapp;
255 struct ntvattr *nvap;
236
237 dprintf(("ntfs_loadnode: loading ino: %d\n",ip->i_number));
238
239 MALLOC(mfrp, struct filerec *, ntfs_bntob(ntmp->ntm_bpmftrec),
240 M_TEMP, M_WAITOK);
241
242 if (ip->i_number < NTFS_SYSNODESNUM) {
243 struct buf *bp;

--- 20 unchanged lines hidden (view full) ---

264 error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
265 ip->i_number * ntfs_bntob(ntmp->ntm_bpmftrec),
266 ntfs_bntob(ntmp->ntm_bpmftrec), mfrp);
267 if (error) {
268 printf("ntfs_loadnode: ntfs_readattr failed\n");
269 goto out;
270 }
271 }
256
257 dprintf(("ntfs_loadnode: loading ino: %d\n",ip->i_number));
258
259 MALLOC(mfrp, struct filerec *, ntfs_bntob(ntmp->ntm_bpmftrec),
260 M_TEMP, M_WAITOK);
261
262 if (ip->i_number < NTFS_SYSNODESNUM) {
263 struct buf *bp;

--- 20 unchanged lines hidden (view full) ---

284 error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
285 ip->i_number * ntfs_bntob(ntmp->ntm_bpmftrec),
286 ntfs_bntob(ntmp->ntm_bpmftrec), mfrp);
287 if (error) {
288 printf("ntfs_loadnode: ntfs_readattr failed\n");
289 goto out;
290 }
291 }
292
272 /* Check if magic and fixups are correct */
273 error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp,
274 ntfs_bntob(ntmp->ntm_bpmftrec));
275 if (error) {
276 printf("ntfs_loadnode: BAD MFT RECORD %d\n",
277 (u_int32_t) ip->i_number);
278 goto out;
279 }
280
281 dprintf(("ntfs_loadnode: load attrs for ino: %d\n",ip->i_number));
282 off = mfrp->fr_attroff;
283 ap = (struct attr *) ((caddr_t)mfrp + off);
293 /* Check if magic and fixups are correct */
294 error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp,
295 ntfs_bntob(ntmp->ntm_bpmftrec));
296 if (error) {
297 printf("ntfs_loadnode: BAD MFT RECORD %d\n",
298 (u_int32_t) ip->i_number);
299 goto out;
300 }
301
302 dprintf(("ntfs_loadnode: load attrs for ino: %d\n",ip->i_number));
303 off = mfrp->fr_attroff;
304 ap = (struct attr *) ((caddr_t)mfrp + off);
284 if (ip->i_vattrp)
285 printf("ntfs_ntloadnode: WARNING! already loaded?\n");
305
306 LIST_INIT(&ip->i_valist);
286
307
287 vapp = &ip->i_vattrp;
288 while (ap->a_hdr.a_type != -1) {
308 while (ap->a_hdr.a_type != -1) {
289 error = ntfs_attrtontvattr(ntmp, vapp, ap);
309 error = ntfs_attrtontvattr(ntmp, &nvap, ap);
290 if (error)
291 break;
310 if (error)
311 break;
292 (*vapp)->va_ip = ip;
293 vapp = &((*vapp)->va_nextp);
312 nvap->va_ip = ip;
294
313
314 LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list);
315
295 off += ap->a_hdr.reclen;
296 ap = (struct attr *) ((caddr_t)mfrp + off);
297 }
298 if (error) {
299 printf("ntfs_loadnode: failed to load attr ino: %d\n",
300 ip->i_number);
301 goto out;
302 }

--- 4 unchanged lines hidden (view full) ---

307
308 ip->i_flag |= IN_LOADED;
309
310out:
311 FREE(mfrp, M_TEMP);
312 return (error);
313}
314
316 off += ap->a_hdr.reclen;
317 ap = (struct attr *) ((caddr_t)mfrp + off);
318 }
319 if (error) {
320 printf("ntfs_loadnode: failed to load attr ino: %d\n",
321 ip->i_number);
322 goto out;
323 }

--- 4 unchanged lines hidden (view full) ---

328
329 ip->i_flag |= IN_LOADED;
330
331out:
332 FREE(mfrp, M_TEMP);
333 return (error);
334}
335
336/*
337 * Routine locks ntnode and increase usecount, just opposite of
338 * ntfs_ntput.
339 */
340int
341ntfs_ntget(
342 struct ntnode *ip)
343{
344 dprintf(("ntfs_ntget: get ntnode %d: %p, usecount: %d\n",
345 ip->i_number, ip, ip->i_usecount));
315
346
347 ip->i_usecount++;
348
349restart:
350 if (ip->i_lock) {
351 while (ip->i_lock) {
352 ip->i_lock = -1;
353 tsleep(&ip->i_lock, PVM, "ntnode", 0);
354 }
355 goto restart;
356 }
357 ip->i_lock = 1;
358
359 return 0;
360}
361
362/*
363 * Routine search ntnode in hash, if found: lock, inc usecount and return.
364 * If not in hash allocate structure for ntnode, prefill it, lock,
365 * inc count and return.
366 *
367 * ntnode returned locked
368 */
316static int ntfs_ntnode_hash_lock;
317int
369static int ntfs_ntnode_hash_lock;
370int
318ntfs_ntget(
371ntfs_ntlookup(
319 struct ntfsmount * ntmp,
320 ino_t ino,
321 struct ntnode ** ipp)
322{
323 struct ntnode *ip;
324
372 struct ntfsmount * ntmp,
373 ino_t ino,
374 struct ntnode ** ipp)
375{
376 struct ntnode *ip;
377
325 dprintf(("ntfs_ntget: ntget ntnode %d\n", ino));
378 dprintf(("ntfs_ntlookup: for ntnode %d\n", ino));
326 *ipp = NULL;
327
328restart:
379 *ipp = NULL;
380
381restart:
329 ip = ntfs_nthashlookup(ntmp->ntm_dev, ino);
382 ip = ntfs_nthashlookup(ntmp->ntm_dev, ino); /* XXX */
330 if (ip) {
383 if (ip) {
331 ip->i_usecount++;
384 ntfs_ntget(ip);
332 *ipp = ip;
385 *ipp = ip;
333 dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
386 dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
334 ino, ip, ip->i_usecount));
335
336 return (0);
337 }
338
339 if (ntfs_ntnode_hash_lock) {
387 ino, ip, ip->i_usecount));
388
389 return (0);
390 }
391
392 if (ntfs_ntnode_hash_lock) {
340 printf("waiting for hash_lock to free...\n");
341 while(ntfs_ntnode_hash_lock) {
342 ntfs_ntnode_hash_lock = -1;
343 tsleep(&ntfs_ntnode_hash_lock, PVM, "ntfsntgt", 0);
344 }
393 while(ntfs_ntnode_hash_lock) {
394 ntfs_ntnode_hash_lock = -1;
395 tsleep(&ntfs_ntnode_hash_lock, PVM, "ntfsntgt", 0);
396 }
345 printf("hash_lock freeed\n");
346 goto restart;
347 }
348 ntfs_ntnode_hash_lock = 1;
349
350 MALLOC(ip, struct ntnode *, sizeof(struct ntnode),
351 M_NTFSNTNODE, M_WAITOK);
397 goto restart;
398 }
399 ntfs_ntnode_hash_lock = 1;
400
401 MALLOC(ip, struct ntnode *, sizeof(struct ntnode),
402 M_NTFSNTNODE, M_WAITOK);
352 ddprintf(("ntfs_ntget: allocating ntnode: %d: %p\n", ino, ip));
403 ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip));
353 bzero((caddr_t) ip, sizeof(struct ntnode));
354
355 /* Generic initialization */
356 ip->i_number = ino;
357 ip->i_mp = ntmp;
358 ip->i_dev = ntmp->ntm_dev;
359 ip->i_uid = ntmp->ntm_uid;
360 ip->i_gid = ntmp->ntm_gid;
361 ip->i_mode = ntmp->ntm_mode;
362 ip->i_usecount++;
363
404 bzero((caddr_t) ip, sizeof(struct ntnode));
405
406 /* Generic initialization */
407 ip->i_number = ino;
408 ip->i_mp = ntmp;
409 ip->i_dev = ntmp->ntm_dev;
410 ip->i_uid = ntmp->ntm_uid;
411 ip->i_gid = ntmp->ntm_gid;
412 ip->i_mode = ntmp->ntm_mode;
413 ip->i_usecount++;
414
415 ip->i_lock = 1;
416
364 LIST_INIT(&ip->i_fnlist);
365
366 ntfs_nthashins(ip);
367
368 if (ntfs_ntnode_hash_lock < 0)
369 wakeup(&ntfs_ntnode_hash_lock);
370 ntfs_ntnode_hash_lock = 0;
371
372 *ipp = ip;
373
417 LIST_INIT(&ip->i_fnlist);
418
419 ntfs_nthashins(ip);
420
421 if (ntfs_ntnode_hash_lock < 0)
422 wakeup(&ntfs_ntnode_hash_lock);
423 ntfs_ntnode_hash_lock = 0;
424
425 *ipp = ip;
426
374 dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
427 dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
375 ino, ip, ip->i_usecount));
376
377 return (0);
378}
379
428 ino, ip, ip->i_usecount));
429
430 return (0);
431}
432
433/*
434 * Decrement usecount of ntnode and unlock it, if usecount reach zero,
435 * deallocate ntnode.
436 *
437 * ntnode should be locked on entry, and unlocked on return.
438 */
380void
439void
381ntfs_ntrele(
382 struct ntnode * ip)
440ntfs_ntput(
441 struct ntnode *ip)
383{
384 struct ntvattr *vap;
385
442{
443 struct ntvattr *vap;
444
386 dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
445 if (!ip->i_lock) printf("ntfs_ntput: NOT LOCKED");
446
447 dprintf(("ntfs_ntput: rele ntnode %d: %p, usecount: %d\n",
387 ip->i_number, ip, ip->i_usecount));
388
389 ip->i_usecount--;
390
391 if (ip->i_usecount < 0) {
448 ip->i_number, ip, ip->i_usecount));
449
450 ip->i_usecount--;
451
452 if (ip->i_usecount < 0) {
392 panic("ntfs_ntrele: ino: %d usecount: %d \n",
453 panic("ntfs_ntput: ino: %d usecount: %d \n",
393 ip->i_number,ip->i_usecount);
394 } else if (ip->i_usecount == 0) {
454 ip->i_number,ip->i_usecount);
455 } else if (ip->i_usecount == 0) {
395 dprintf(("ntfs_ntrele: deallocating ntnode: %d\n",
456 dprintf(("ntfs_ntput: deallocating ntnode: %d\n",
396 ip->i_number));
397
398 if (ip->i_fnlist.lh_first)
457 ip->i_number));
458
459 if (ip->i_fnlist.lh_first)
399 panic("ntfs_ntrele: ntnode has fnodes\n");
460 panic("ntfs_ntput: ntnode has fnodes\n");
400
401 ntfs_nthashrem(ip);
402
461
462 ntfs_nthashrem(ip);
463
403 while (ip->i_vattrp) {
404 vap = ip->i_vattrp;
405 ip->i_vattrp = vap->va_nextp;
464 while (ip->i_valist.lh_first != NULL) {
465 vap = ip->i_valist.lh_first;
466 LIST_REMOVE(vap,va_list);
406 ntfs_freentvattr(vap);
407 }
408 FREE(ip, M_NTFSNTNODE);
467 ntfs_freentvattr(vap);
468 }
469 FREE(ip, M_NTFSNTNODE);
470 } else {
471 if (ip->i_lock < 0)
472 wakeup(&ip->i_lock);
473 ip->i_lock = 0;
409 }
474 }
410 dprintf(("ntfs_ntrele: rele ok\n"));
411}
412
475}
476
477/*
478 * Decrement usecount of ntnode.
479 */
413void
480void
481ntfs_ntrele(
482 struct ntnode * ip)
483{
484 dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
485 ip->i_number, ip, ip->i_usecount));
486
487 ip->i_usecount--;
488
489 if (ip->i_usecount < 0)
490 panic("ntfs_ntrele: ino: %d usecount: %d \n",
491 ip->i_number,ip->i_usecount);
492}
493
494/*
495 * Deallocate all memory allocated for ntvattr by call to
496 * ntfs_attrtontvattr and some other functions.
497 */
498void
414ntfs_freentvattr(
415 struct ntvattr * vap)
416{
417 if (vap->va_flag & NTFS_AF_INRUN) {
418 if (vap->va_vruncn)
419 FREE(vap->va_vruncn, M_NTFSRUN);
420 if (vap->va_vruncl)
421 FREE(vap->va_vruncl, M_NTFSRUN);
422 } else {
423 if (vap->va_datap)
424 FREE(vap->va_datap, M_NTFSRDATA);
425 }
426 FREE(vap, M_NTFSNTVATTR);
427}
428
499ntfs_freentvattr(
500 struct ntvattr * vap)
501{
502 if (vap->va_flag & NTFS_AF_INRUN) {
503 if (vap->va_vruncn)
504 FREE(vap->va_vruncn, M_NTFSRUN);
505 if (vap->va_vruncl)
506 FREE(vap->va_vruncl, M_NTFSRUN);
507 } else {
508 if (vap->va_datap)
509 FREE(vap->va_datap, M_NTFSRDATA);
510 }
511 FREE(vap, M_NTFSNTVATTR);
512}
513
514/*
515 * Convert disk image of attribute into ntvattr structure,
516 * runs are expanded also.
517 */
429int
430ntfs_attrtontvattr(
431 struct ntfsmount * ntmp,
432 struct ntvattr ** rvapp,
433 struct attr * rap)
434{
435 int error, i;
436 struct ntvattr *vap;

--- 51 unchanged lines hidden (view full) ---

488 else
489 *rvapp = vap;
490
491 ddprintf(("\n"));
492
493 return (error);
494}
495
518int
519ntfs_attrtontvattr(
520 struct ntfsmount * ntmp,
521 struct ntvattr ** rvapp,
522 struct attr * rap)
523{
524 int error, i;
525 struct ntvattr *vap;

--- 51 unchanged lines hidden (view full) ---

577 else
578 *rvapp = vap;
579
580 ddprintf(("\n"));
581
582 return (error);
583}
584
585/*
586 * Expand run into more utilizable and more memory eating format.
587 */
496int
497ntfs_runtovrun(
498 cn_t ** rcnp,
499 cn_t ** rclp,
500 u_long * rcntp,
501 u_int8_t * run)
502{
503 u_int32_t off;

--- 43 unchanged lines hidden (view full) ---

547 cnt++;
548 }
549 *rcnp = cn;
550 *rclp = cl;
551 *rcntp = cnt;
552 return (0);
553}
554
588int
589ntfs_runtovrun(
590 cn_t ** rcnp,
591 cn_t ** rclp,
592 u_long * rcntp,
593 u_int8_t * run)
594{
595 u_int32_t off;

--- 43 unchanged lines hidden (view full) ---

639 cnt++;
640 }
641 *rcnp = cn;
642 *rclp = cl;
643 *rcntp = cnt;
644 return (0);
645}
646
555
647/*
648 * Convert wchar to uppercase wchar, should be macros?
649 */
556wchar
557ntfs_toupper(
558 struct ntfsmount * ntmp,
559 wchar wc)
560{
561 return (ntmp->ntm_upcase[wc & 0xFF]);
562}
563
650wchar
651ntfs_toupper(
652 struct ntfsmount * ntmp,
653 wchar wc)
654{
655 return (ntmp->ntm_upcase[wc & 0xFF]);
656}
657
658/*
659 * Compare to unicode strings case insensible.
660 */
564int
565ntfs_uustricmp(
566 struct ntfsmount * ntmp,
567 wchar * str1,
568 int str1len,
569 wchar * str2,
570 int str2len)
571{

--- 4 unchanged lines hidden (view full) ---

576 res = (int) ntfs_toupper(ntmp, str1[i]) -
577 (int) ntfs_toupper(ntmp, str2[i]);
578 if (res)
579 return res;
580 }
581 return (str1len - str2len);
582}
583
661int
662ntfs_uustricmp(
663 struct ntfsmount * ntmp,
664 wchar * str1,
665 int str1len,
666 wchar * str2,
667 int str2len)
668{

--- 4 unchanged lines hidden (view full) ---

673 res = (int) ntfs_toupper(ntmp, str1[i]) -
674 (int) ntfs_toupper(ntmp, str2[i]);
675 if (res)
676 return res;
677 }
678 return (str1len - str2len);
679}
680
681/*
682 * Compare unicode and ascii string case insens.
683 */
584int
585ntfs_uastricmp(
586 struct ntfsmount * ntmp,
587 wchar * str1,
588 int str1len,
589 char *str2,
590 int str2len)
591{

--- 4 unchanged lines hidden (view full) ---

596 res = (int) ntfs_toupper(ntmp, str1[i]) -
597 (int) ntfs_toupper(ntmp, (wchar) str2[i]);
598 if (res)
599 return res;
600 }
601 return (str1len - str2len);
602}
603
684int
685ntfs_uastricmp(
686 struct ntfsmount * ntmp,
687 wchar * str1,
688 int str1len,
689 char *str2,
690 int str2len)
691{

--- 4 unchanged lines hidden (view full) ---

696 res = (int) ntfs_toupper(ntmp, str1[i]) -
697 (int) ntfs_toupper(ntmp, (wchar) str2[i]);
698 if (res)
699 return res;
700 }
701 return (str1len - str2len);
702}
703
704/*
705 * Compare unicode and ascii string case sens.
706 */
604int
605ntfs_uastrcmp(
606 struct ntfsmount * ntmp,
607 wchar * str1,
608 int str1len,
609 char *str2,
610 int str2len)
611{
612 int i;
613 int res;
614
615 for (i = 0; (i < str1len) && (i < str2len); i++) {
616 res = ((int) str1[i]) - ((int) str2[i]);
617 if (res)
618 return res;
619 }
620 return (str1len - str2len);
621}
622
707int
708ntfs_uastrcmp(
709 struct ntfsmount * ntmp,
710 wchar * str1,
711 int str1len,
712 char *str2,
713 int str2len)
714{
715 int i;
716 int res;
717
718 for (i = 0; (i < str1len) && (i < str2len); i++) {
719 res = ((int) str1[i]) - ((int) str2[i]);
720 if (res)
721 return res;
722 }
723 return (str1len - str2len);
724}
725
726/*
727 * Search fnode in ntnode, if not found allocate and preinitialize.
728 *
729 * ntnode should be locked on entry.
730 */
623int
624ntfs_fget(
625 struct ntfsmount *ntmp,
626 struct ntnode *ip,
627 int attrtype,
628 char *attrname,
629 struct fnode **fpp)
630{
731int
732ntfs_fget(
733 struct ntfsmount *ntmp,
734 struct ntnode *ip,
735 int attrtype,
736 char *attrname,
737 struct fnode **fpp)
738{
631 int error;
632 struct fnode *fp;
633
634 dprintf(("ntfs_fget: ino: %d, attrtype: 0x%x, attrname: %s\n",
635 ip->i_number,attrtype, attrname?attrname:""));
636 *fpp = NULL;
637 for (fp = ip->i_fnlist.lh_first; fp != NULL; fp = fp->f_fnlist.le_next){
638 dprintf(("ntfs_fget: fnode: attrtype: %d, attrname: %s\n",
639 fp->f_attrtype, fp->f_attrname?fp->f_attrname:""));

--- 17 unchanged lines hidden (view full) ---

657 fp->f_devvp = ntmp->ntm_devvp;
658 fp->f_dev = ntmp->ntm_dev;
659 fp->f_mp = ntmp;
660
661 fp->f_ip = ip;
662 fp->f_attrname = attrname;
663 if (fp->f_attrname) fp->f_flag |= FN_AATTRNAME;
664 fp->f_attrtype = attrtype;
739 struct fnode *fp;
740
741 dprintf(("ntfs_fget: ino: %d, attrtype: 0x%x, attrname: %s\n",
742 ip->i_number,attrtype, attrname?attrname:""));
743 *fpp = NULL;
744 for (fp = ip->i_fnlist.lh_first; fp != NULL; fp = fp->f_fnlist.le_next){
745 dprintf(("ntfs_fget: fnode: attrtype: %d, attrname: %s\n",
746 fp->f_attrtype, fp->f_attrname?fp->f_attrname:""));

--- 17 unchanged lines hidden (view full) ---

764 fp->f_devvp = ntmp->ntm_devvp;
765 fp->f_dev = ntmp->ntm_dev;
766 fp->f_mp = ntmp;
767
768 fp->f_ip = ip;
769 fp->f_attrname = attrname;
770 if (fp->f_attrname) fp->f_flag |= FN_AATTRNAME;
771 fp->f_attrtype = attrtype;
665 if ((fp->f_attrtype == NTFS_A_DATA) && (fp->f_attrname == NULL))
666 fp->f_flag |= FN_DEFAULT;
667 else {
668 error = ntfs_filesize(ntmp, fp, &fp->f_size, &fp->f_allocated);
669 if (error) {
670 FREE(fp,M_NTFSFNODE);
671 return (error);
672 }
673 }
674
675 ntfs_ntref(ip);
676
677 LIST_INSERT_HEAD(&ip->i_fnlist, fp, f_fnlist);
678
679 *fpp = fp;
680
681 return (0);
682}
683
772
773 ntfs_ntref(ip);
774
775 LIST_INSERT_HEAD(&ip->i_fnlist, fp, f_fnlist);
776
777 *fpp = fp;
778
779 return (0);
780}
781
782/*
783 * Deallocate fnode, remove it from ntnode's fnode list.
784 *
785 * ntnode should be locked.
786 */
684void
685ntfs_frele(
686 struct fnode *fp)
687{
688 struct ntnode *ip = FTONT(fp);
689
690 dprintf(("ntfs_frele: fnode: %p for %d: %p\n", fp, ip->i_number, ip));
691
692 dprintf(("ntfs_frele: deallocating fnode\n"));
693 LIST_REMOVE(fp,f_fnlist);
694 if (fp->f_flag & FN_AATTRNAME)
695 FREE(fp->f_attrname, M_TEMP);
696 if (fp->f_dirblbuf)
697 FREE(fp->f_dirblbuf, M_NTFSDIR);
698 FREE(fp, M_NTFSFNODE);
699 ntfs_ntrele(ip);
700}
701
787void
788ntfs_frele(
789 struct fnode *fp)
790{
791 struct ntnode *ip = FTONT(fp);
792
793 dprintf(("ntfs_frele: fnode: %p for %d: %p\n", fp, ip->i_number, ip));
794
795 dprintf(("ntfs_frele: deallocating fnode\n"));
796 LIST_REMOVE(fp,f_fnlist);
797 if (fp->f_flag & FN_AATTRNAME)
798 FREE(fp->f_attrname, M_TEMP);
799 if (fp->f_dirblbuf)
800 FREE(fp->f_dirblbuf, M_NTFSDIR);
801 FREE(fp, M_NTFSFNODE);
802 ntfs_ntrele(ip);
803}
804
805/*
806 * Lookup attribute name in format: [[:$ATTR_TYPE]:$ATTR_NAME],
807 * $ATTR_TYPE is searched in attrdefs read from $AttrDefs.
808 * If $ATTR_TYPE nott specifed, ATTR_A_DATA assumed.
809 */
702int
703ntfs_ntlookupattr(
704 struct ntfsmount * ntmp,
705 char * name,
706 int namelen,
707 int *attrtype,
708 char **attrname)
709{

--- 38 unchanged lines hidden (view full) ---

748 MALLOC((*attrname), char *, namelen, M_TEMP, M_WAITOK);
749 memcpy((*attrname), name, namelen);
750 (*attrname)[namelen] = '\0';
751 *attrtype = NTFS_A_DATA;
752 }
753
754 return (0);
755}
810int
811ntfs_ntlookupattr(
812 struct ntfsmount * ntmp,
813 char * name,
814 int namelen,
815 int *attrtype,
816 char **attrname)
817{

--- 38 unchanged lines hidden (view full) ---

856 MALLOC((*attrname), char *, namelen, M_TEMP, M_WAITOK);
857 memcpy((*attrname), name, namelen);
858 (*attrname)[namelen] = '\0';
859 *attrtype = NTFS_A_DATA;
860 }
861
862 return (0);
863}
864
756/*
757 * Lookup specifed node for filename, matching cnp,
758 * return fnode filled.
759 */
760int
865/*
866 * Lookup specifed node for filename, matching cnp,
867 * return fnode filled.
868 */
869int
761ntfs_ntlookup(
870ntfs_ntlookupfile(
762 struct ntfsmount * ntmp,
763 struct vnode * vp,
764 struct componentname * cnp,
765 struct vnode ** vpp)
766{
767 struct fnode *fp = VTOF(vp);
768 struct ntnode *ip = FTONT(fp);
769 struct ntvattr *vap; /* Root attribute */
770 cn_t cn; /* VCN in current attribute */
771 caddr_t rdbuf; /* Buffer to read directory's blocks */
772 u_int32_t blsize;
773 u_int32_t rdsize; /* Length of data to read from current block */
774 struct attr_indexentry *iep;
775 int error, res, anamelen, fnamelen;
776 char *fname,*aname;
777 u_int32_t aoff;
778
871 struct ntfsmount * ntmp,
872 struct vnode * vp,
873 struct componentname * cnp,
874 struct vnode ** vpp)
875{
876 struct fnode *fp = VTOF(vp);
877 struct ntnode *ip = FTONT(fp);
878 struct ntvattr *vap; /* Root attribute */
879 cn_t cn; /* VCN in current attribute */
880 caddr_t rdbuf; /* Buffer to read directory's blocks */
881 u_int32_t blsize;
882 u_int32_t rdsize; /* Length of data to read from current block */
883 struct attr_indexentry *iep;
884 int error, res, anamelen, fnamelen;
885 char *fname,*aname;
886 u_int32_t aoff;
887
888 error = ntfs_ntget(ip);
889 if (error)
890 return (error);
891
779 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
780 if (error || (vap->va_flag & NTFS_AF_INRUN))
781 return (ENOTDIR);
782
783 blsize = vap->va_a_iroot->ir_size;
784 rdsize = vap->va_datalen;
785
892 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
893 if (error || (vap->va_flag & NTFS_AF_INRUN))
894 return (ENOTDIR);
895
896 blsize = vap->va_a_iroot->ir_size;
897 rdsize = vap->va_datalen;
898
899 /*
900 * Divide file name into: foofilefoofilefoofile[:attrspec]
901 * Store like this: fname:fnamelen [aname:anamelen]
902 */
786 fname = cnp->cn_nameptr;
787 aname = NULL;
788 anamelen = 0;
789 for (fnamelen = 0; fnamelen < cnp->cn_namelen; fnamelen++)
790 if(fname[fnamelen] == ':') {
791 aname = fname + fnamelen + 1;
792 anamelen = cnp->cn_namelen - fnamelen - 1;
903 fname = cnp->cn_nameptr;
904 aname = NULL;
905 anamelen = 0;
906 for (fnamelen = 0; fnamelen < cnp->cn_namelen; fnamelen++)
907 if(fname[fnamelen] == ':') {
908 aname = fname + fnamelen + 1;
909 anamelen = cnp->cn_namelen - fnamelen - 1;
793 dprintf(("ntfs_ntlookup: file %s (%d), attr: %s (%d)\n",
910 dprintf(("ntfs_ntlookupfile: %s (%d), attr: %s (%d)\n",
794 fname, fnamelen, aname, anamelen));
795 break;
796 }
797
911 fname, fnamelen, aname, anamelen));
912 break;
913 }
914
798 dprintf(("ntfs_ntlookup: blocksize: %d, rdsize: %d\n", blsize, rdsize));
915 dprintf(("ntfs_ntlookupfile: blksz: %d, rdsz: %d\n", blsize, rdsize));
799
800 MALLOC(rdbuf, caddr_t, blsize, M_TEMP, M_WAITOK);
801
802 error = ntfs_readattr(ntmp, ip, NTFS_A_INDXROOT, "$I30",
803 0, rdsize, rdbuf);
804 if (error)
805 goto fail;
806

--- 44 unchanged lines hidden (view full) ---

851 }
852
853 /* vget node, but don't load it */
854 error = ntfs_vgetex(ntmp->ntm_mountp,
855 iep->ie_number,
856 attrtype,
857 attrname,
858 LK_EXCLUSIVE,
916
917 MALLOC(rdbuf, caddr_t, blsize, M_TEMP, M_WAITOK);
918
919 error = ntfs_readattr(ntmp, ip, NTFS_A_INDXROOT, "$I30",
920 0, rdsize, rdbuf);
921 if (error)
922 goto fail;
923

--- 44 unchanged lines hidden (view full) ---

968 }
969
970 /* vget node, but don't load it */
971 error = ntfs_vgetex(ntmp->ntm_mountp,
972 iep->ie_number,
973 attrtype,
974 attrname,
975 LK_EXCLUSIVE,
859 VG_DONTLOAD,
976 VG_DONTLOADIN |
977 VG_DONTVALIDFN,
860 curproc,
861 &nvp);
862 if(error)
863 goto fail;
864
865 nfp = VTOF(nvp);
866
978 curproc,
979 &nvp);
980 if(error)
981 goto fail;
982
983 nfp = VTOF(nvp);
984
985 if (nfp->f_flag & FN_VALID) {
986 *vpp = nvp;
987 goto fail;
988 }
989
867 nfp->f_fflag = iep->ie_fflag;
868 nfp->f_pnumber = iep->ie_fpnumber;
869 nfp->f_times = iep->ie_ftimes;
870
871 if((nfp->f_fflag & NTFS_FFLAG_DIR) &&
872 (nfp->f_attrtype == NTFS_A_DATA) &&
873 (nfp->f_attrname == NULL))
874 nfp->f_type = VDIR;
875 else
876 nfp->f_type = VREG;
877
878 nvp->v_type = nfp->f_type;
879
880 if ((nfp->f_attrtype == NTFS_A_DATA) &&
881 (nfp->f_attrname == NULL)) {
882 /* Opening default attribute */
883 nfp->f_size = iep->ie_fsize;
884 nfp->f_allocated = iep->ie_fallocated;
885 nfp->f_flag |= FN_PRELOADED;
990 nfp->f_fflag = iep->ie_fflag;
991 nfp->f_pnumber = iep->ie_fpnumber;
992 nfp->f_times = iep->ie_ftimes;
993
994 if((nfp->f_fflag & NTFS_FFLAG_DIR) &&
995 (nfp->f_attrtype == NTFS_A_DATA) &&
996 (nfp->f_attrname == NULL))
997 nfp->f_type = VDIR;
998 else
999 nfp->f_type = VREG;
1000
1001 nvp->v_type = nfp->f_type;
1002
1003 if ((nfp->f_attrtype == NTFS_A_DATA) &&
1004 (nfp->f_attrname == NULL)) {
1005 /* Opening default attribute */
1006 nfp->f_size = iep->ie_fsize;
1007 nfp->f_allocated = iep->ie_fallocated;
1008 nfp->f_flag |= FN_PRELOADED;
1009 } else {
1010 error = ntfs_filesize(ntmp, nfp,
1011 &nfp->f_size,
1012 &nfp->f_allocated);
1013 if (error) {
1014 vput(nvp);
1015 goto fail;
1016 }
886 }
1017 }
1018
1019 nfp->f_flag &= ~FN_VALID;
887 *vpp = nvp;
888 goto fail;
889 }
890 } else if (res > 0)
891 break;
892
893 aoff += iep->reclen;
894 iep = (struct attr_indexentry *) (rdbuf + aoff);
895 }
896
897 /* Dive if possible */
898 if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
1020 *vpp = nvp;
1021 goto fail;
1022 }
1023 } else if (res > 0)
1024 break;
1025
1026 aoff += iep->reclen;
1027 iep = (struct attr_indexentry *) (rdbuf + aoff);
1028 }
1029
1030 /* Dive if possible */
1031 if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
899 dprintf(("ntfs_ntlookup: diving\n"));
1032 dprintf(("ntfs_ntlookupfile: diving\n"));
900
901 cn = *(cn_t *) (rdbuf + aoff +
902 iep->reclen - sizeof(cn_t));
903 rdsize = blsize;
904
905 error = ntfs_readattr(ntmp, ip, NTFS_A_INDX, "$I30",
906 ntfs_cntob(cn), rdsize, rdbuf);
907 if (error)
908 goto fail;
909
910 error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC,
911 rdbuf, rdsize);
912 if (error)
913 goto fail;
914
915 aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize +
916 0x18);
917 } else {
1033
1034 cn = *(cn_t *) (rdbuf + aoff +
1035 iep->reclen - sizeof(cn_t));
1036 rdsize = blsize;
1037
1038 error = ntfs_readattr(ntmp, ip, NTFS_A_INDX, "$I30",
1039 ntfs_cntob(cn), rdsize, rdbuf);
1040 if (error)
1041 goto fail;
1042
1043 error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC,
1044 rdbuf, rdsize);
1045 if (error)
1046 goto fail;
1047
1048 aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize +
1049 0x18);
1050 } else {
918 dprintf(("ntfs_ntlookup: nowhere to dive :-(\n"));
1051 dprintf(("ntfs_ntlookupfile: nowhere to dive :-(\n"));
919 error = ENOENT;
920 break;
921 }
922 } while (1);
923
924 dprintf(("finish\n"));
925
926fail:
927 ntfs_ntvattrrele(vap);
1052 error = ENOENT;
1053 break;
1054 }
1055 } while (1);
1056
1057 dprintf(("finish\n"));
1058
1059fail:
1060 ntfs_ntvattrrele(vap);
1061 ntfs_ntput(ip);
928 FREE(rdbuf, M_TEMP);
929 return (error);
930}
931
1062 FREE(rdbuf, M_TEMP);
1063 return (error);
1064}
1065
1066/*
1067 * Check if name type is permitted to show.
1068 */
932int
933ntfs_isnamepermitted(
934 struct ntfsmount * ntmp,
935 struct attr_indexentry * iep)
936{
937
938 if (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)
939 return 1;
940
941 switch (iep->ie_fnametype) {
942 case 2:
943 ddprintf(("ntfs_isnamepermitted: skiped DOS name\n"));
944 return 0;
1069int
1070ntfs_isnamepermitted(
1071 struct ntfsmount * ntmp,
1072 struct attr_indexentry * iep)
1073{
1074
1075 if (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)
1076 return 1;
1077
1078 switch (iep->ie_fnametype) {
1079 case 2:
1080 ddprintf(("ntfs_isnamepermitted: skiped DOS name\n"));
1081 return 0;
945 case 0:
946 case 1:
947 case 3:
1082 case 0: case 1: case 3:
948 return 1;
949 default:
950 printf("ntfs_isnamepermitted: " \
951 "WARNING! Unknown file name type: %d\n",
952 iep->ie_fnametype);
953 break;
954 }
955 return 0;
956}
957
1083 return 1;
1084 default:
1085 printf("ntfs_isnamepermitted: " \
1086 "WARNING! Unknown file name type: %d\n",
1087 iep->ie_fnametype);
1088 break;
1089 }
1090 return 0;
1091}
1092
1093/*
1094 * Read ntfs dir like stream of attr_indexentry, not like btree of them.
1095 * This is done by scaning $BITMAP:$I30 for busy clusters and reading them.
1096 * Ofcouse $INDEX_ROOT:$I30 is read before. Last read values are stored in
1097 * fnode, so we can skip toward record number num almost immediatly.
1098 * Anyway this is rather slow routine. The problem is that we don't know
1099 * how many records are there in $INDEX_ALLOCATION:$I30 block.
1100 */
958int
959ntfs_ntreaddir(
960 struct ntfsmount * ntmp,
961 struct fnode * fp,
962 u_int32_t num,
963 struct attr_indexentry ** riepp)
964{
965 struct ntnode *ip = FTONT(fp);

--- 7 unchanged lines hidden (view full) ---

973 u_int32_t attrnum; /* Current attribute type */
974 u_int32_t cpbl = 1; /* Clusters per directory block */
975 u_int32_t blnum;
976 struct attr_indexentry *iep;
977 int error = ENOENT;
978 u_int32_t aoff, cnum;
979
980 dprintf(("ntfs_ntreaddir: read ino: %d, num: %d\n", ip->i_number, num));
1101int
1102ntfs_ntreaddir(
1103 struct ntfsmount * ntmp,
1104 struct fnode * fp,
1105 u_int32_t num,
1106 struct attr_indexentry ** riepp)
1107{
1108 struct ntnode *ip = FTONT(fp);

--- 7 unchanged lines hidden (view full) ---

1116 u_int32_t attrnum; /* Current attribute type */
1117 u_int32_t cpbl = 1; /* Clusters per directory block */
1118 u_int32_t blnum;
1119 struct attr_indexentry *iep;
1120 int error = ENOENT;
1121 u_int32_t aoff, cnum;
1122
1123 dprintf(("ntfs_ntreaddir: read ino: %d, num: %d\n", ip->i_number, num));
1124 error = ntfs_ntget(ip);
1125 if (error)
1126 return (error);
1127
981 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
982 if (error)
983 return (ENOTDIR);
984
985 if (fp->f_dirblbuf == NULL) {
986 fp->f_dirblsz = vap->va_a_iroot->ir_size;
987 MALLOC(fp->f_dirblbuf, caddr_t,
988 max(vap->va_datalen,fp->f_dirblsz), M_NTFSDIR, M_WAITOK);

--- 112 unchanged lines hidden (view full) ---

1101 if (vap)
1102 ntfs_ntvattrrele(vap);
1103 if (bmvap)
1104 ntfs_ntvattrrele(bmvap);
1105 if (iavap)
1106 ntfs_ntvattrrele(iavap);
1107 if (bmp)
1108 FREE(bmp, M_TEMP);
1128 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
1129 if (error)
1130 return (ENOTDIR);
1131
1132 if (fp->f_dirblbuf == NULL) {
1133 fp->f_dirblsz = vap->va_a_iroot->ir_size;
1134 MALLOC(fp->f_dirblbuf, caddr_t,
1135 max(vap->va_datalen,fp->f_dirblsz), M_NTFSDIR, M_WAITOK);

--- 112 unchanged lines hidden (view full) ---

1248 if (vap)
1249 ntfs_ntvattrrele(vap);
1250 if (bmvap)
1251 ntfs_ntvattrrele(bmvap);
1252 if (iavap)
1253 ntfs_ntvattrrele(iavap);
1254 if (bmp)
1255 FREE(bmp, M_TEMP);
1256 ntfs_ntput(ip);
1109 return (error);
1110}
1257 return (error);
1258}
1259
1111/*
1260/*
1112 * #undef dprintf #define dprintf(a)
1261 * Convert NTFS times that are in 100 ns units and begins from
1262 * 1601 Jan 1 into unix times.
1113 */
1263 */
1114
1115struct timespec
1116ntfs_nttimetounix(
1117 u_int64_t nt)
1118{
1119 struct timespec t;
1120
1121 /* WindowNT times are in 100 ns and from 1601 Jan 1 */
1122 t.tv_nsec = (nt % (1000 * 1000 * 10)) * 100;
1123 t.tv_sec = nt / (1000 * 1000 * 10) -
1124 369LL * 365LL * 24LL * 60LL * 60LL -
1125 89LL * 1LL * 24LL * 60LL * 60LL;
1126 return (t);
1127}
1128
1264struct timespec
1265ntfs_nttimetounix(
1266 u_int64_t nt)
1267{
1268 struct timespec t;
1269
1270 /* WindowNT times are in 100 ns and from 1601 Jan 1 */
1271 t.tv_nsec = (nt % (1000 * 1000 * 10)) * 100;
1272 t.tv_sec = nt / (1000 * 1000 * 10) -
1273 369LL * 365LL * 24LL * 60LL * 60LL -
1274 89LL * 1LL * 24LL * 60LL * 60LL;
1275 return (t);
1276}
1277
1278/*
1279 * Get file times from NTFS_A_NAME attribute.
1280 */
1129int
1130ntfs_times(
1131 struct ntfsmount * ntmp,
1132 struct ntnode * ip,
1133 ntfs_times_t * tm)
1134{
1135 struct ntvattr *vap;
1136 int error;
1137
1138 dprintf(("ntfs_times: ino: %d...\n", ip->i_number));
1281int
1282ntfs_times(
1283 struct ntfsmount * ntmp,
1284 struct ntnode * ip,
1285 ntfs_times_t * tm)
1286{
1287 struct ntvattr *vap;
1288 int error;
1289
1290 dprintf(("ntfs_times: ino: %d...\n", ip->i_number));
1139 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
1291
1292 error = ntfs_ntget(ip);
1140 if (error)
1141 return (error);
1293 if (error)
1294 return (error);
1295
1296 error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
1297 if (error) {
1298 ntfs_ntput(ip);
1299 return (error);
1300 }
1142 *tm = vap->va_a_name->n_times;
1143 ntfs_ntvattrrele(vap);
1301 *tm = vap->va_a_name->n_times;
1302 ntfs_ntvattrrele(vap);
1303 ntfs_ntput(ip);
1144
1145 return (0);
1146}
1147
1304
1305 return (0);
1306}
1307
1308/*
1309 * Get file sizes from corresponding attribute.
1310 *
1311 * ntnode under fnode should be locked.
1312 */
1148int
1149ntfs_filesize(
1150 struct ntfsmount * ntmp,
1151 struct fnode * fp,
1152 u_int64_t * size,
1153 u_int64_t * bytes)
1154{
1155 struct ntvattr *vap;
1156 struct ntnode *ip = FTONT(fp);
1157 u_int64_t sz, bn;
1158 int error;
1159
1160 dprintf(("ntfs_filesize: ino: %d\n", ip->i_number));
1313int
1314ntfs_filesize(
1315 struct ntfsmount * ntmp,
1316 struct fnode * fp,
1317 u_int64_t * size,
1318 u_int64_t * bytes)
1319{
1320 struct ntvattr *vap;
1321 struct ntnode *ip = FTONT(fp);
1322 u_int64_t sz, bn;
1323 int error;
1324
1325 dprintf(("ntfs_filesize: ino: %d\n", ip->i_number));
1161 if (fp->f_flag & FN_DEFAULT) {
1162 error = ntfs_ntvattrget(ntmp, ip,
1163 NTFS_A_DATA, NULL, 0, &vap);
1164 } else {
1165 error = ntfs_ntvattrget(ntmp, ip,
1166 fp->f_attrtype, fp->f_attrname, 0, &vap);
1167 }
1326
1327 error = ntfs_ntvattrget(ntmp, ip,
1328 fp->f_attrtype, fp->f_attrname, 0, &vap);
1168 if (error)
1169 return (error);
1329 if (error)
1330 return (error);
1331
1170 bn = vap->va_allocated;
1171 sz = vap->va_datalen;
1172
1173 dprintf(("ntfs_filesize: %d bytes (%d bytes allocated)\n",
1174 (u_int32_t) sz, (u_int32_t) bn));
1175
1176 if (size)
1177 *size = sz;
1178 if (bytes)
1179 *bytes = bn;
1180
1181 ntfs_ntvattrrele(vap);
1182
1183 return (0);
1184}
1185
1332 bn = vap->va_allocated;
1333 sz = vap->va_datalen;
1334
1335 dprintf(("ntfs_filesize: %d bytes (%d bytes allocated)\n",
1336 (u_int32_t) sz, (u_int32_t) bn));
1337
1338 if (size)
1339 *size = sz;
1340 if (bytes)
1341 *bytes = bn;
1342
1343 ntfs_ntvattrrele(vap);
1344
1345 return (0);
1346}
1347
1348/*
1349 * This is one of write routine.
1350 *
1351 * ntnode should be locked.
1352 */
1186int
1187ntfs_writeattr_plain(
1188 struct ntfsmount * ntmp,
1189 struct ntnode * ip,
1190 u_int32_t attrnum,
1191 char *attrname,
1192 off_t roff,
1193 size_t rsize,

--- 35 unchanged lines hidden (view full) ---

1229 off += towrite;
1230 data = data + towrite;
1231 *initp += init;
1232 }
1233
1234 return (error);
1235}
1236
1353int
1354ntfs_writeattr_plain(
1355 struct ntfsmount * ntmp,
1356 struct ntnode * ip,
1357 u_int32_t attrnum,
1358 char *attrname,
1359 off_t roff,
1360 size_t rsize,

--- 35 unchanged lines hidden (view full) ---

1396 off += towrite;
1397 data = data + towrite;
1398 *initp += init;
1399 }
1400
1401 return (error);
1402}
1403
1404/*
1405 * This is one of write routine.
1406 *
1407 * ntnode should be locked.
1408 */
1237int
1238ntfs_writentvattr_plain(
1239 struct ntfsmount * ntmp,
1240 struct ntnode * ip,
1241 struct ntvattr * vap,
1242 off_t roff,
1243 size_t rsize,
1244 void *rdata,

--- 63 unchanged lines hidden (view full) ---

1308 ntfs_cntob(cl),
1309 NOCRED, &bp);
1310 if (error) {
1311 brelse(bp);
1312 return (error);
1313 }
1314 }
1315 memcpy(bp->b_data + off, data, tocopy);
1409int
1410ntfs_writentvattr_plain(
1411 struct ntfsmount * ntmp,
1412 struct ntnode * ip,
1413 struct ntvattr * vap,
1414 off_t roff,
1415 size_t rsize,
1416 void *rdata,

--- 63 unchanged lines hidden (view full) ---

1480 ntfs_cntob(cl),
1481 NOCRED, &bp);
1482 if (error) {
1483 brelse(bp);
1484 return (error);
1485 }
1486 }
1487 memcpy(bp->b_data + off, data, tocopy);
1316 bwrite(bp);
1488 bawrite(bp);
1317 data = data + tocopy;
1318 *initp += tocopy;
1319 off = 0;
1320 left -= tocopy;
1321 cn += cl;
1322 ccl -= cl;
1323 }
1324 }

--- 6 unchanged lines hidden (view full) ---

1331 } else {
1332 printf("ntfs_writevattr_plain: CAN'T WRITE RES. ATTRIBUTE\n");
1333 error = ENOTTY;
1334 }
1335
1336 return (error);
1337}
1338
1489 data = data + tocopy;
1490 *initp += tocopy;
1491 off = 0;
1492 left -= tocopy;
1493 cn += cl;
1494 ccl -= cl;
1495 }
1496 }

--- 6 unchanged lines hidden (view full) ---

1503 } else {
1504 printf("ntfs_writevattr_plain: CAN'T WRITE RES. ATTRIBUTE\n");
1505 error = ENOTTY;
1506 }
1507
1508 return (error);
1509}
1510
1511/*
1512 * This is one of read routines.
1513 *
1514 * ntnode should be locked.
1515 */
1339int
1340ntfs_readntvattr_plain(
1341 struct ntfsmount * ntmp,
1342 struct ntnode * ip,
1343 struct ntvattr * vap,
1344 off_t roff,
1345 size_t rsize,
1346 void *rdata,

--- 27 unchanged lines hidden (view full) ---

1374 (u_int32_t) left, (u_int32_t) ccn, \
1375 (u_int32_t) ccl, (u_int32_t) off));
1376
1377 if (ntfs_cntob(ccl) < off) {
1378 off -= ntfs_cntob(ccl);
1379 cnt++;
1380 continue;
1381 }
1516int
1517ntfs_readntvattr_plain(
1518 struct ntfsmount * ntmp,
1519 struct ntnode * ip,
1520 struct ntvattr * vap,
1521 off_t roff,
1522 size_t rsize,
1523 void *rdata,

--- 27 unchanged lines hidden (view full) ---

1551 (u_int32_t) left, (u_int32_t) ccn, \
1552 (u_int32_t) ccl, (u_int32_t) off));
1553
1554 if (ntfs_cntob(ccl) < off) {
1555 off -= ntfs_cntob(ccl);
1556 cnt++;
1557 continue;
1558 }
1382 if (ccn || ip->i_number == NTFS_BOOTINO) { /* XXX */
1559 if (ccn || ip->i_number == NTFS_BOOTINO) {
1383 ccl -= ntfs_btocn(off);
1384 cn = ccn + ntfs_btocn(off);
1385 off = ntfs_btocnoff(off);
1386
1387 while (left && ccl) {
1388 tocopy = min(left,
1389 min(ntfs_cntob(ccl) - off,
1390 MAXBSIZE - off));

--- 46 unchanged lines hidden (view full) ---

1437 ddprintf(("ntfs_readnvattr_plain: data is in mft record\n"));
1438 memcpy(rdata, vap->va_datap + roff, rsize);
1439 *initp += rsize;
1440 }
1441
1442 return (error);
1443}
1444
1560 ccl -= ntfs_btocn(off);
1561 cn = ccn + ntfs_btocn(off);
1562 off = ntfs_btocnoff(off);
1563
1564 while (left && ccl) {
1565 tocopy = min(left,
1566 min(ntfs_cntob(ccl) - off,
1567 MAXBSIZE - off));

--- 46 unchanged lines hidden (view full) ---

1614 ddprintf(("ntfs_readnvattr_plain: data is in mft record\n"));
1615 memcpy(rdata, vap->va_datap + roff, rsize);
1616 *initp += rsize;
1617 }
1618
1619 return (error);
1620}
1621
1622/*
1623 * This is one of read routines.
1624 *
1625 * ntnode should be locked.
1626 */
1445int
1446ntfs_readattr_plain(
1447 struct ntfsmount * ntmp,
1448 struct ntnode * ip,
1449 u_int32_t attrnum,
1450 char *attrname,
1451 off_t roff,
1452 size_t rsize,

--- 35 unchanged lines hidden (view full) ---

1488 off += toread;
1489 data = data + toread;
1490 *initp += init;
1491 }
1492
1493 return (error);
1494}
1495
1627int
1628ntfs_readattr_plain(
1629 struct ntfsmount * ntmp,
1630 struct ntnode * ip,
1631 u_int32_t attrnum,
1632 char *attrname,
1633 off_t roff,
1634 size_t rsize,

--- 35 unchanged lines hidden (view full) ---

1670 off += toread;
1671 data = data + toread;
1672 *initp += init;
1673 }
1674
1675 return (error);
1676}
1677
1678/*
1679 * This is one of read routines.
1680 *
1681 * ntnode should be locked.
1682 */
1496int
1497ntfs_readattr(
1498 struct ntfsmount * ntmp,
1499 struct ntnode * ip,
1500 u_int32_t attrnum,
1501 char *attrname,
1502 off_t roff,
1503 size_t rsize,

--- 65 unchanged lines hidden (view full) ---

1569 FREE(cup, M_NTFSDECOMP);
1570 } else
1571 error = ntfs_readattr_plain(ntmp, ip, attrnum, attrname,
1572 roff, rsize, rdata, &init);
1573 ntfs_ntvattrrele(vap);
1574 return (error);
1575}
1576
1683int
1684ntfs_readattr(
1685 struct ntfsmount * ntmp,
1686 struct ntnode * ip,
1687 u_int32_t attrnum,
1688 char *attrname,
1689 off_t roff,
1690 size_t rsize,

--- 65 unchanged lines hidden (view full) ---

1756 FREE(cup, M_NTFSDECOMP);
1757 } else
1758 error = ntfs_readattr_plain(ntmp, ip, attrnum, attrname,
1759 roff, rsize, rdata, &init);
1760 ntfs_ntvattrrele(vap);
1761 return (error);
1762}
1763
1764#if UNUSED_CODE
1577int
1578ntfs_parserun(
1579 cn_t * cn,
1580 cn_t * cl,
1581 u_int8_t * run,
1582 u_long len,
1583 u_long *off)
1584{

--- 26 unchanged lines hidden (view full) ---

1611 sz, len, *off);
1612 return (EINVAL);
1613 }
1614 for (i = 0; i < (sz & 0xF); i++)
1615 *cn += (u_int32_t) run[(*off)++] << (i << 3);
1616
1617 return (0);
1618}
1765int
1766ntfs_parserun(
1767 cn_t * cn,
1768 cn_t * cl,
1769 u_int8_t * run,
1770 u_long len,
1771 u_long *off)
1772{

--- 26 unchanged lines hidden (view full) ---

1799 sz, len, *off);
1800 return (EINVAL);
1801 }
1802 for (i = 0; i < (sz & 0xF); i++)
1803 *cn += (u_int32_t) run[(*off)++] << (i << 3);
1804
1805 return (0);
1806}
1807#endif
1619
1808
1809/*
1810 * Process fixup routine on given buffer.
1811 */
1620int
1621ntfs_procfixups(
1622 struct ntfsmount * ntmp,
1623 u_int32_t magic,
1624 caddr_t buf,
1625 size_t len)
1626{
1627 struct fixuphdr *fhp = (struct fixuphdr *) buf;

--- 26 unchanged lines hidden (view full) ---

1654 return (EINVAL);
1655 }
1656 *cfxp = *fxp;
1657 ((caddr_t) cfxp) += ntmp->ntm_bps;
1658 }
1659 return (0);
1660}
1661
1812int
1813ntfs_procfixups(
1814 struct ntfsmount * ntmp,
1815 u_int32_t magic,
1816 caddr_t buf,
1817 size_t len)
1818{
1819 struct fixuphdr *fhp = (struct fixuphdr *) buf;

--- 26 unchanged lines hidden (view full) ---

1846 return (EINVAL);
1847 }
1848 *cfxp = *fxp;
1849 ((caddr_t) cfxp) += ntmp->ntm_bps;
1850 }
1851 return (0);
1852}
1853
1854#if UNUSED_CODE
1662int
1663ntfs_runtocn(
1664 cn_t * cn,
1665 struct ntfsmount * ntmp,
1666 u_int8_t * run,
1667 u_long len,
1668 cn_t vcn)
1669{

--- 26 unchanged lines hidden (view full) ---

1696 if (error) {
1697 printf("ntfs_runtocn: ntfs_parserun failed\n");
1698 return (error);
1699 }
1700 } while (ccl <= vcn);
1701 *cn = ccn + vcn;
1702 return (0);
1703}
1855int
1856ntfs_runtocn(
1857 cn_t * cn,
1858 struct ntfsmount * ntmp,
1859 u_int8_t * run,
1860 u_long len,
1861 cn_t vcn)
1862{

--- 26 unchanged lines hidden (view full) ---

1889 if (error) {
1890 printf("ntfs_runtocn: ntfs_parserun failed\n");
1891 return (error);
1892 }
1893 } while (ccl <= vcn);
1894 *cn = ccn + vcn;
1895 return (0);
1896}
1897#endif