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 |
|