ReactOS  0.4.15-dev-4914-g2220e56
write.c File Reference
#include "btrfs_drv.h"
Include dependency graph for write.c:

Go to the source code of this file.

Classes

struct  write_stripe
 
struct  stripe
 
struct  log_stripe
 

Functions

 _Function_class_ (IO_COMPLETION_ROUTINE)
 
 __attribute__ ((nonnull(1)))
 
 __attribute__ ((nonnull(1, 2)))
 
 __attribute__ ((nonnull(1, 3)))
 
 __attribute__ ((nonnull(1, 3, 5, 8)))
 
 __attribute__ ((nonnull(1, 2, 5)))
 
 __attribute__ ((nonnull(1, 2, 4, 6, 10)))
 
 __attribute__ ((nonnull(1, 3, 5)))
 
 __attribute__ ((nonnull(1, 4, 5)))
 
 __attribute__ ((nonnull(2, 3)))
 
 __attribute__ ((nonnull(1, 2, 3)))
 
 __attribute__ ((nonnull(1, 2, 6)))
 
 __attribute__ ((nonnull(1, 3, 7)))
 
 _Requires_lock_held_ (c->lock) _When_(return !=0
 
 _Releases_lock_ (c->lock)) __attribute__((nonnull(1
 
bool insert_extent_chunk (_In_ device_extension *Vcb, _In_ fcb *fcb, _In_ chunk *c, _In_ uint64_t start_data, _In_ uint64_t length, _In_ bool prealloc, _In_opt_ void *data, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback, _In_ uint8_t compression, _In_ uint64_t decoded_size, _In_ bool file_write, _In_ uint64_t irp_offset)
 
 __attribute__ ((nonnull(1, 2, 5, 7, 10)))
 
 __attribute__ ((nonnull(1, 4)))
 
 __attribute__ ((nonnull(1, 2, 5, 9)))
 
 __attribute__ ((nonnull(1, 6)))
 
 __attribute__ ((nonnull(1, 2, 5, 6, 11)))
 
 __attribute__ ((nonnull(1, 2, 4, 5, 11)))
 
 _Dispatch_type_ (IRP_MJ_WRITE)
 

Function Documentation

◆ __attribute__() [1/18]

__attribute__ ( (nonnull(1))  )

Definition at line 90 of file write.c.

91  {
92  LIST_ENTRY* le2;
93 
94  ExAcquireResourceSharedLite(&Vcb->chunk_lock, true);
95 
96  le2 = Vcb->chunks.Flink;
97  while (le2 != &Vcb->chunks) {
99 
100  if (address >= c->offset && address < c->offset + c->chunk_item->size) {
101  ExReleaseResourceLite(&Vcb->chunk_lock);
102  return c;
103  }
104 
105  le2 = le2->Flink;
106  }
107 
108  ExReleaseResourceLite(&Vcb->chunk_lock);
109 
110  return NULL;
111 }
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
GLintptr offset
Definition: glext.h:5920
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
Definition: typedefs.h:119
Definition: list.h:27
#define NULL
Definition: types.h:112
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define c
Definition: ke_i.h:80

◆ __attribute__() [2/18]

__attribute__ ( (nonnull(1, 2))  )

Definition at line 140 of file write.c.

141  {
142  uint64_t devusage = 0xffffffffffffffff;
143  space *devdh1 = NULL, *devdh2 = NULL;
144  LIST_ENTRY* le;
145  device* dev2 = NULL;
146 
147  le = Vcb->devices.Flink;
148 
149  while (le != &Vcb->devices) {
151 
152  if (!dev->readonly && !dev->reloc && dev->devobj) {
153  uint64_t usage = (dev->devitem.bytes_used * 4096) / dev->devitem.num_bytes;
154 
155  // favour devices which have been used the least
156  if (usage < devusage) {
157  if (!IsListEmpty(&dev->space)) {
158  LIST_ENTRY* le2;
159  space *dh1 = NULL, *dh2 = NULL;
160 
161  le2 = dev->space.Flink;
162  while (le2 != &dev->space) {
164 
165  if (dh->size >= max_stripe_size && (!dh1 || !dh2 || dh->size < dh1->size)) {
166  dh2 = dh1;
167  dh1 = dh;
168  }
169 
170  le2 = le2->Flink;
171  }
172 
173  if (dh1 && (dh2 || dh1->size >= 2 * max_stripe_size)) {
174  dev2 = dev;
175  devusage = usage;
176  devdh1 = dh1;
177  devdh2 = dh2 ? dh2 : dh1;
178  }
179  }
180  }
181  }
182 
183  le = le->Flink;
184  }
185 
186  if (!devdh1) {
187  uint64_t size = 0;
188 
189  // Can't find hole of at least max_stripe_size; look for the largest one we can find
190 
191  if (full_size)
192  return false;
193 
194  le = Vcb->devices.Flink;
195  while (le != &Vcb->devices) {
197 
198  if (!dev->readonly && !dev->reloc) {
199  if (!IsListEmpty(&dev->space)) {
200  LIST_ENTRY* le2;
201  space *dh1 = NULL, *dh2 = NULL;
202 
203  le2 = dev->space.Flink;
204  while (le2 != &dev->space) {
206 
207  if (!dh1 || !dh2 || dh->size < dh1->size) {
208  dh2 = dh1;
209  dh1 = dh;
210  }
211 
212  le2 = le2->Flink;
213  }
214 
215  if (dh1) {
216  uint64_t devsize;
217 
218  if (dh2)
219  devsize = max(dh1->size / 2, min(dh1->size, dh2->size));
220  else
221  devsize = dh1->size / 2;
222 
223  if (devsize > size) {
224  dev2 = dev;
225  devdh1 = dh1;
226 
227  if (dh2 && min(dh1->size, dh2->size) > dh1->size / 2)
228  devdh2 = dh2;
229  else
230  devdh2 = dh1;
231 
232  size = devsize;
233  }
234  }
235  }
236  }
237 
238  le = le->Flink;
239  }
240 
241  if (!devdh1)
242  return false;
243  }
244 
245  stripes[0].device = stripes[1].device = dev2;
246  stripes[0].dh = devdh1;
247  stripes[1].dh = devdh2;
248 
249  return true;
250 }
#define max(a, b)
Definition: svc.c:63
if(dx==0 &&dy==0)
Definition: linetemp.h:174
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static int dev
Definition: mkdosfs.c:536
Definition: devices.h:37
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
GLsizeiptr size
Definition: glext.h:5919
#define Vcb
Definition: cdprocs.h:1415
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
Definition: typedefs.h:119
uint64_t size
Definition: btrfs_drv.h:512
UINT64 uint64_t
Definition: types.h:77
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
#define NULL
Definition: types.h:112

◆ __attribute__() [3/18]

__attribute__ ( (nonnull(1, 3))  )

Definition at line 366 of file write.c.

367  {
369  uint64_t max_stripe_size, max_chunk_size, stripe_size, stripe_length, factor;
370  uint64_t total_size = 0, logaddr;
371  uint16_t i, type, num_stripes, sub_stripes, max_stripes, min_stripes, allowed_missing;
372  stripe* stripes = NULL;
373  uint16_t cisize;
374  CHUNK_ITEM_STRIPE* cis;
375  chunk* c = NULL;
376  space* s = NULL;
377  LIST_ENTRY* le;
378 
379  le = Vcb->devices.Flink;
380  while (le != &Vcb->devices) {
382  total_size += dev->devitem.num_bytes;
383 
384  le = le->Flink;
385  }
386 
387  TRACE("total_size = %I64x\n", total_size);
388 
389  // We purposely check for DATA first - mixed blocks have the same size
390  // as DATA ones.
391  if (flags & BLOCK_FLAG_DATA) {
392  max_stripe_size = 0x40000000; // 1 GB
393  max_chunk_size = 10 * max_stripe_size;
394  } else if (flags & BLOCK_FLAG_METADATA) {
395  if (total_size > 0xC80000000) // 50 GB
396  max_stripe_size = 0x40000000; // 1 GB
397  else
398  max_stripe_size = 0x10000000; // 256 MB
399 
400  max_chunk_size = max_stripe_size;
401  } else if (flags & BLOCK_FLAG_SYSTEM) {
402  max_stripe_size = 0x2000000; // 32 MB
403  max_chunk_size = 2 * max_stripe_size;
404  } else {
405  ERR("unknown chunk type\n");
406  return STATUS_INTERNAL_ERROR;
407  }
408 
409  if (flags & BLOCK_FLAG_DUPLICATE) {
410  min_stripes = 2;
411  max_stripes = 2;
412  sub_stripes = 0;
414  allowed_missing = 0;
415  } else if (flags & BLOCK_FLAG_RAID0) {
416  min_stripes = 2;
417  max_stripes = (uint16_t)min(0xffff, Vcb->superblock.num_devices);
418  sub_stripes = 0;
420  allowed_missing = 0;
421  } else if (flags & BLOCK_FLAG_RAID1) {
422  min_stripes = 2;
423  max_stripes = 2;
424  sub_stripes = 1;
426  allowed_missing = 1;
427  } else if (flags & BLOCK_FLAG_RAID10) {
428  min_stripes = 4;
429  max_stripes = (uint16_t)min(0xffff, Vcb->superblock.num_devices);
430  sub_stripes = 2;
432  allowed_missing = 1;
433  } else if (flags & BLOCK_FLAG_RAID5) {
434  min_stripes = 3;
435  max_stripes = (uint16_t)min(0xffff, Vcb->superblock.num_devices);
436  sub_stripes = 1;
438  allowed_missing = 1;
439  } else if (flags & BLOCK_FLAG_RAID6) {
440  min_stripes = 4;
441  max_stripes = 257;
442  sub_stripes = 1;
444  allowed_missing = 2;
445  } else if (flags & BLOCK_FLAG_RAID1C3) {
446  min_stripes = 3;
447  max_stripes = 3;
448  sub_stripes = 1;
450  allowed_missing = 2;
451  } else if (flags & BLOCK_FLAG_RAID1C4) {
452  min_stripes = 4;
453  max_stripes = 4;
454  sub_stripes = 1;
456  allowed_missing = 3;
457  } else { // SINGLE
458  min_stripes = 1;
459  max_stripes = 1;
460  sub_stripes = 1;
461  type = 0;
462  allowed_missing = 0;
463  }
464 
465  if (max_chunk_size > total_size / 10) { // cap at 10%
466  max_chunk_size = total_size / 10;
467  max_stripe_size = max_chunk_size / min_stripes;
468  }
469 
470  if (max_stripe_size > total_size / (10 * min_stripes))
471  max_stripe_size = total_size / (10 * min_stripes);
472 
473  TRACE("would allocate a new chunk of %I64x bytes and stripe %I64x\n", max_chunk_size, max_stripe_size);
474 
475  stripes = ExAllocatePoolWithTag(PagedPool, sizeof(stripe) * max_stripes, ALLOC_TAG);
476  if (!stripes) {
477  ERR("out of memory\n");
479  goto end;
480  }
481 
482  num_stripes = 0;
483 
484  if (type == BLOCK_FLAG_DUPLICATE) {
485  if (!find_new_dup_stripes(Vcb, stripes, max_stripe_size, full_size)) {
487  goto end;
488  } else
489  num_stripes = max_stripes;
490  } else {
491  for (i = 0; i < max_stripes; i++) {
492  if (!find_new_stripe(Vcb, stripes, i, max_stripe_size, false, full_size))
493  break;
494  else
495  num_stripes++;
496  }
497  }
498 
499  if (num_stripes < min_stripes && Vcb->options.allow_degraded && allowed_missing > 0) {
500  uint16_t added_missing = 0;
501 
502  for (i = num_stripes; i < max_stripes; i++) {
503  if (!find_new_stripe(Vcb, stripes, i, max_stripe_size, true, full_size))
504  break;
505  else {
506  added_missing++;
507  if (added_missing >= allowed_missing)
508  break;
509  }
510  }
511 
512  num_stripes += added_missing;
513  }
514 
515  // for RAID10, round down to an even number of stripes
516  if (type == BLOCK_FLAG_RAID10 && (num_stripes % sub_stripes) != 0) {
517  num_stripes -= num_stripes % sub_stripes;
518  }
519 
520  if (num_stripes < min_stripes) {
521  WARN("found %u stripes, needed at least %u\n", num_stripes, min_stripes);
523  goto end;
524  }
525 
527  if (!c) {
528  ERR("out of memory\n");
530  goto end;
531  }
532 
533  c->devices = NULL;
534 
535  cisize = sizeof(CHUNK_ITEM) + (num_stripes * sizeof(CHUNK_ITEM_STRIPE));
536  c->chunk_item = ExAllocatePoolWithTag(NonPagedPool, cisize, ALLOC_TAG);
537  if (!c->chunk_item) {
538  ERR("out of memory\n");
540  goto end;
541  }
542 
543  stripe_length = 0x10000; // FIXME? BTRFS_STRIPE_LEN in kernel
544 
545  if (type == BLOCK_FLAG_DUPLICATE && stripes[1].dh == stripes[0].dh)
546  stripe_size = min(stripes[0].dh->size / 2, max_stripe_size);
547  else {
548  stripe_size = max_stripe_size;
549  for (i = 0; i < num_stripes; i++) {
550  if (stripes[i].dh->size < stripe_size)
551  stripe_size = stripes[i].dh->size;
552  }
553  }
554 
555  if (type == BLOCK_FLAG_RAID0)
556  factor = num_stripes;
557  else if (type == BLOCK_FLAG_RAID10)
558  factor = num_stripes / sub_stripes;
559  else if (type == BLOCK_FLAG_RAID5)
560  factor = num_stripes - 1;
561  else if (type == BLOCK_FLAG_RAID6)
562  factor = num_stripes - 2;
563  else
564  factor = 1; // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4
565 
566  if (stripe_size * factor > max_chunk_size)
567  stripe_size = max_chunk_size / factor;
568 
569  if (stripe_size % stripe_length > 0)
570  stripe_size -= stripe_size % stripe_length;
571 
572  if (stripe_size == 0) {
573  ERR("not enough free space found (stripe_size == 0)\n");
575  goto end;
576  }
577 
578  c->chunk_item->size = stripe_size * factor;
579  c->chunk_item->root_id = Vcb->extent_root->id;
580  c->chunk_item->stripe_length = stripe_length;
581  c->chunk_item->type = flags;
582  c->chunk_item->opt_io_alignment = (uint32_t)c->chunk_item->stripe_length;
583  c->chunk_item->opt_io_width = (uint32_t)c->chunk_item->stripe_length;
584  c->chunk_item->sector_size = stripes[0].device->devitem.minimal_io_size;
585  c->chunk_item->num_stripes = num_stripes;
586  c->chunk_item->sub_stripes = sub_stripes;
587 
588  c->devices = ExAllocatePoolWithTag(NonPagedPool, sizeof(device*) * num_stripes, ALLOC_TAG);
589  if (!c->devices) {
590  ERR("out of memory\n");
592  goto end;
593  }
594 
595  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
596  for (i = 0; i < num_stripes; i++) {
597  cis[i].dev_id = stripes[i].device->devitem.dev_id;
598 
599  if (type == BLOCK_FLAG_DUPLICATE && i == 1 && stripes[i].dh == stripes[0].dh)
600  cis[i].offset = stripes[0].dh->address + stripe_size;
601  else
602  cis[i].offset = stripes[i].dh->address;
603 
604  cis[i].dev_uuid = stripes[i].device->devitem.device_uuid;
605 
606  c->devices[i] = stripes[i].device;
607  }
608 
609  logaddr = find_new_chunk_address(Vcb, c->chunk_item->size);
610 
611  Vcb->superblock.chunk_root_generation = Vcb->superblock.generation;
612 
613  c->size = cisize;
614  c->offset = logaddr;
615  c->used = c->oldused = 0;
616  c->cache = c->old_cache = NULL;
617  c->readonly = false;
618  c->reloc = false;
619  c->last_alloc_set = false;
620  c->last_stripe = 0;
621  c->cache_loaded = true;
622  c->changed = false;
623  c->space_changed = false;
624  c->balance_num = 0;
625 
626  InitializeListHead(&c->space);
627  InitializeListHead(&c->space_size);
628  InitializeListHead(&c->deleting);
629  InitializeListHead(&c->changed_extents);
630 
631  InitializeListHead(&c->range_locks);
632  ExInitializeResourceLite(&c->range_locks_lock);
633  KeInitializeEvent(&c->range_locks_event, NotificationEvent, false);
634 
635  InitializeListHead(&c->partial_stripes);
636  ExInitializeResourceLite(&c->partial_stripes_lock);
637 
638  ExInitializeResourceLite(&c->lock);
639  ExInitializeResourceLite(&c->changed_extents_lock);
640 
642  if (!s) {
643  ERR("out of memory\n");
645  goto end;
646  }
647 
648  s->address = c->offset;
649  s->size = c->chunk_item->size;
650  InsertTailList(&c->space, &s->list_entry);
651  InsertTailList(&c->space_size, &s->list_entry_size);
652 
654 
655  for (i = 0; i < num_stripes; i++) {
656  stripes[i].device->devitem.bytes_used += stripe_size;
657 
658  space_list_subtract2(&stripes[i].device->space, NULL, cis[i].offset, stripe_size, NULL, NULL);
659  }
660 
662 
664  Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_RAID56;
665 
666 end:
667  if (stripes)
668  ExFreePool(stripes);
669 
670  if (!NT_SUCCESS(Status)) {
671  if (c) {
672  if (c->devices)
673  ExFreePool(c->devices);
674 
675  if (c->chunk_item)
676  ExFreePool(c->chunk_item);
677 
678  ExFreePool(c);
679  }
680 
681  if (s) ExFreePool(s);
682  } else {
683  bool done = false;
684 
685  le = Vcb->chunks.Flink;
686  while (le != &Vcb->chunks) {
688 
689  if (c2->offset > c->offset) {
690  InsertHeadList(le->Blink, &c->list_entry);
691  done = true;
692  break;
693  }
694 
695  le = le->Flink;
696  }
697 
698  if (!done)
699  InsertTailList(&Vcb->chunks, &c->list_entry);
700 
701  c->created = true;
702  c->changed = true;
703  c->space_changed = true;
704  c->list_entry_balance.Flink = NULL;
705 
706  *pc = c;
707  }
708 
709  return Status;
710 }
LIST_ENTRY space
Definition: btrfs_drv.h:532
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
uint64_t dev_id
Definition: btrfs.h:352
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint factor
Definition: glfuncs.h:178
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
uint64_t offset
Definition: btrfs_drv.h:557
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
Definition: write.c:113
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
#define InsertTailList(ListHead, Entry)
uint64_t address
Definition: btrfs_drv.h:511
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:87
uint64_t offset
Definition: btrfs.h:353
Definition: devices.h:37
#define BLOCK_FLAG_RAID1C3
Definition: btrfs.h:87
#define BLOCK_FLAG_SYSTEM
Definition: shellext.h:76
#define BLOCK_FLAG_RAID10
Definition: shellext.h:81
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BTRFS_UUID device_uuid
Definition: btrfs.h:190
Status
Definition: gdiplustypes.h:24
#define BLOCK_FLAG_RAID0
Definition: shellext.h:78
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
#define for
Definition: utility.h:88
BTRFS_UUID dev_uuid
Definition: btrfs.h:354
#define BLOCK_FLAG_RAID6
Definition: shellext.h:83
GLbitfield flags
Definition: glext.h:7161
GLuint GLuint end
Definition: gl.h:1545
#define BLOCK_FLAG_RAID1C4
Definition: btrfs.h:88
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
void protect_superblocks(_Inout_ chunk *c)
Definition: btrfs.c:3746
#define BLOCK_FLAG_METADATA
Definition: shellext.h:77
uint64_t dev_id
Definition: btrfs.h:178
GLdouble s
Definition: gl.h:2039
Definition: typedefs.h:119
#define ERR(fmt,...)
Definition: debug.h:110
device * device
Definition: write.c:115
uint64_t size
Definition: btrfs_drv.h:512
UINT64 uint64_t
Definition: types.h:77
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
space * dh
Definition: write.c:114
void space_list_subtract2(LIST_ENTRY *list, LIST_ENTRY *list_size, uint64_t address, uint64_t length, chunk *c, LIST_ENTRY *rollback)
Definition: free-space.c:2155
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
DEV_ITEM devitem
Definition: btrfs_drv.h:520
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
#define BLOCK_FLAG_DATA
Definition: shellext.h:75
uint32_t minimal_io_size
Definition: btrfs.h:183
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
uint64_t bytes_used
Definition: btrfs.h:180
#define c
Definition: ke_i.h:80
#define BTRFS_INCOMPAT_FLAGS_RAID56
Definition: btrfs.h:122
#define BLOCK_FLAG_DUPLICATE
Definition: shellext.h:80
#define STATUS_SUCCESS
Definition: shellext.h:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define BLOCK_FLAG_RAID5
Definition: shellext.h:82
#define uint32_t
Definition: nsiface.idl:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BLOCK_FLAG_RAID1
Definition: shellext.h:79

◆ __attribute__() [4/18]

__attribute__ ( (nonnull(1, 3, 5, 8))  )

Definition at line 712 of file write.c.

714  {
715  uint64_t startoff, endoff;
716  uint16_t startoffstripe, endoffstripe, stripenum;
717  uint64_t pos, *stripeoff;
718  uint32_t i;
719  bool file_write = Irp && Irp->MdlAddress && (Irp->MdlAddress->ByteOffset == 0);
720  PMDL master_mdl;
721  PFN_NUMBER* pfns;
722 
723  stripeoff = ExAllocatePoolWithTag(PagedPool, sizeof(uint64_t) * c->chunk_item->num_stripes, ALLOC_TAG);
724  if (!stripeoff) {
725  ERR("out of memory\n");
727  }
728 
729  get_raid0_offset(address - c->offset, c->chunk_item->stripe_length, c->chunk_item->num_stripes, &startoff, &startoffstripe);
730  get_raid0_offset(address + length - c->offset - 1, c->chunk_item->stripe_length, c->chunk_item->num_stripes, &endoff, &endoffstripe);
731 
732  if (file_write) {
733  master_mdl = Irp->MdlAddress;
734 
735  pfns = (PFN_NUMBER*)(Irp->MdlAddress + 1);
736  pfns = &pfns[irp_offset >> PAGE_SHIFT];
737  } else if (((ULONG_PTR)data % PAGE_SIZE) != 0) {
739  if (!wtc->scratch) {
740  ERR("out of memory\n");
742  }
743 
744  RtlCopyMemory(wtc->scratch, data, length);
745 
746  master_mdl = IoAllocateMdl(wtc->scratch, length, false, false, NULL);
747  if (!master_mdl) {
748  ERR("out of memory\n");
750  }
751 
752  MmBuildMdlForNonPagedPool(master_mdl);
753 
754  wtc->mdl = master_mdl;
755 
756  pfns = (PFN_NUMBER*)(master_mdl + 1);
757  } else {
759 
760  master_mdl = IoAllocateMdl(data, length, false, false, NULL);
761  if (!master_mdl) {
762  ERR("out of memory\n");
764  }
765 
766  _SEH2_TRY {
770  } _SEH2_END;
771 
772  if (!NT_SUCCESS(Status)) {
773  ERR("MmProbeAndLockPages threw exception %08lx\n", Status);
774  IoFreeMdl(master_mdl);
775  return Status;
776  }
777 
778  wtc->mdl = master_mdl;
779 
780  pfns = (PFN_NUMBER*)(master_mdl + 1);
781  }
782 
783  for (i = 0; i < c->chunk_item->num_stripes; i++) {
784  if (startoffstripe > i)
785  stripes[i].start = startoff - (startoff % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
786  else if (startoffstripe == i)
787  stripes[i].start = startoff;
788  else
789  stripes[i].start = startoff - (startoff % c->chunk_item->stripe_length);
790 
791  if (endoffstripe > i)
792  stripes[i].end = endoff - (endoff % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
793  else if (endoffstripe == i)
794  stripes[i].end = endoff + 1;
795  else
796  stripes[i].end = endoff - (endoff % c->chunk_item->stripe_length);
797 
798  if (stripes[i].start != stripes[i].end) {
799  stripes[i].mdl = IoAllocateMdl(NULL, (ULONG)(stripes[i].end - stripes[i].start), false, false, NULL);
800  if (!stripes[i].mdl) {
801  ERR("IoAllocateMdl failed\n");
802  ExFreePool(stripeoff);
804  }
805  }
806  }
807 
808  pos = 0;
809  RtlZeroMemory(stripeoff, sizeof(uint64_t) * c->chunk_item->num_stripes);
810 
811  stripenum = startoffstripe;
812 
813  while (pos < length) {
814  PFN_NUMBER* stripe_pfns = (PFN_NUMBER*)(stripes[stripenum].mdl + 1);
815 
816  if (pos == 0) {
817  uint32_t writelen = (uint32_t)min(stripes[stripenum].end - stripes[stripenum].start,
818  c->chunk_item->stripe_length - (stripes[stripenum].start % c->chunk_item->stripe_length));
819 
820  RtlCopyMemory(stripe_pfns, pfns, writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
821 
822  stripeoff[stripenum] += writelen;
823  pos += writelen;
824  } else if (length - pos < c->chunk_item->stripe_length) {
825  RtlCopyMemory(&stripe_pfns[stripeoff[stripenum] >> PAGE_SHIFT], &pfns[pos >> PAGE_SHIFT], (ULONG)((length - pos) * sizeof(PFN_NUMBER) >> PAGE_SHIFT));
826  break;
827  } else {
828  RtlCopyMemory(&stripe_pfns[stripeoff[stripenum] >> PAGE_SHIFT], &pfns[pos >> PAGE_SHIFT], (ULONG)(c->chunk_item->stripe_length * sizeof(PFN_NUMBER) >> PAGE_SHIFT));
829 
830  stripeoff[stripenum] += c->chunk_item->stripe_length;
831  pos += c->chunk_item->stripe_length;
832  }
833 
834  stripenum = (stripenum + 1) % c->chunk_item->num_stripes;
835  }
836 
837  ExFreePool(stripeoff);
838 
839  return STATUS_SUCCESS;
840 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
LONG NTSTATUS
Definition: precomp.h:26
unsigned short int uint16_t
Definition: acefiex.h:54
if(dx==0 &&dy==0)
Definition: linetemp.h:174
_Post_satisfies_ static stripe __inline void get_raid0_offset(_In_ uint64_t off, _In_ uint64_t stripe_length, _In_ uint16_t num_stripes, _Out_ uint64_t *stripeoff, _Out_ uint16_t *stripe)
Definition: btrfs_drv.h:989
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ALLOC_TAG
Definition: btrfs_drv.h:87
ULONG PFN_NUMBER
Definition: ke.h:9
_In_ PIRP Irp
Definition: csq.h:116
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
MDL * mdl
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define ERR(fmt,...)
Definition: debug.h:110
_SEH2_END
Definition: create.c:4400
UINT64 uint64_t
Definition: types.h:77
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLuint start
Definition: gl.h:1545
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define uint32_t
Definition: nsiface.idl:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ __attribute__() [5/18]

__attribute__ ( (nonnull(1, 2, 5))  )

Definition at line 982 of file write.c.

983  {
985  LIST_ENTRY* le;
986  partial_stripe* ps;
987  uint64_t stripe_addr;
988  uint16_t num_data_stripes;
989 
990  num_data_stripes = c->chunk_item->num_stripes - (c->chunk_item->type & BLOCK_FLAG_RAID5 ? 1 : 2);
991  stripe_addr = address - ((address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length));
992 
993  ExAcquireResourceExclusiveLite(&c->partial_stripes_lock, true);
994 
995  le = c->partial_stripes.Flink;
996  while (le != &c->partial_stripes) {
998 
999  if (ps->address == stripe_addr) {
1000  // update existing entry
1001 
1002  RtlCopyMemory(ps->data + address - stripe_addr, data, length);
1003  RtlClearBits(&ps->bmp, (ULONG)((address - stripe_addr) >> Vcb->sector_shift), length >> Vcb->sector_shift);
1004 
1005  // if now filled, flush
1006  if (RtlAreBitsClear(&ps->bmp, 0, (ULONG)((num_data_stripes * c->chunk_item->stripe_length) >> Vcb->sector_shift))) {
1007  Status = flush_partial_stripe(Vcb, c, ps);
1008  if (!NT_SUCCESS(Status)) {
1009  ERR("flush_partial_stripe returned %08lx\n", Status);
1010  goto end;
1011  }
1012 
1014 
1015  if (ps->bmparr)
1016  ExFreePool(ps->bmparr);
1017 
1018  ExFreePool(ps);
1019  }
1020 
1022  goto end;
1023  } else if (ps->address > stripe_addr)
1024  break;
1025 
1026  le = le->Flink;
1027  }
1028 
1029  // add new entry
1030 
1031  ps = ExAllocatePoolWithTag(NonPagedPool, offsetof(partial_stripe, data[0]) + (ULONG)(num_data_stripes * c->chunk_item->stripe_length), ALLOC_TAG);
1032  if (!ps) {
1033  ERR("out of memory\n");
1035  goto end;
1036  }
1037 
1038  ps->bmplen = (ULONG)(num_data_stripes * c->chunk_item->stripe_length) >> Vcb->sector_shift;
1039 
1040  ps->address = stripe_addr;
1041  ps->bmparr = ExAllocatePoolWithTag(NonPagedPool, (size_t)sector_align(((ps->bmplen / 8) + 1), sizeof(ULONG)), ALLOC_TAG);
1042  if (!ps->bmparr) {
1043  ERR("out of memory\n");
1044  ExFreePool(ps);
1046  goto end;
1047  }
1048 
1049  RtlInitializeBitMap(&ps->bmp, ps->bmparr, ps->bmplen);
1050  RtlSetAllBits(&ps->bmp);
1051 
1052  RtlCopyMemory(ps->data + address - stripe_addr, data, length);
1053  RtlClearBits(&ps->bmp, (ULONG)((address - stripe_addr) >> Vcb->sector_shift), length >> Vcb->sector_shift);
1054 
1055  InsertHeadList(le->Blink, &ps->list_entry);
1056 
1058 
1059 end:
1060  ExReleaseResourceLite(&c->partial_stripes_lock);
1061 
1062  return Status;
1063 }
ULONG * bmparr
Definition: btrfs_drv.h:547
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS flush_partial_stripe(device_extension *Vcb, chunk *c, partial_stripe *ps)
Definition: flushthread.c:5840
uint64_t address
Definition: btrfs_drv.h:546
RTL_BITMAP bmp
Definition: btrfs_drv.h:549
unsigned short int uint16_t
Definition: acefiex.h:54
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
LIST_ENTRY list_entry
Definition: btrfs_drv.h:550
#define offsetof(TYPE, MEMBER)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint8_t data[1]
Definition: btrfs_drv.h:551
Definition: typedefs.h:119
#define ERR(fmt,...)
Definition: debug.h:110
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
UINT64 uint64_t
Definition: types.h:77
Definition: list.h:27
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSYSAPI BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP, ULONG, ULONG)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define BLOCK_FLAG_RAID5
Definition: shellext.h:82
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ __attribute__() [6/18]

__attribute__ ( (nonnull(1, 2, 4, 6, 10))  )

Definition at line 1070 of file write.c.

1072  {
1073  uint64_t startoff, endoff, parity_start, parity_end;
1074  uint16_t startoffstripe, endoffstripe, parity, num_data_stripes = c->chunk_item->num_stripes - 1;
1075  uint64_t pos, parity_pos, *stripeoff = NULL;
1076  uint32_t i;
1077  bool file_write = Irp && Irp->MdlAddress && (Irp->MdlAddress->ByteOffset == 0);
1078  PMDL master_mdl;
1079  NTSTATUS Status;
1080  PFN_NUMBER *pfns, *parity_pfns;
1081  log_stripe* log_stripes = NULL;
1082 
1083  if ((address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) {
1084  uint64_t delta = (address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length);
1085 
1086  delta = min(length, delta);
1087  Status = add_partial_stripe(Vcb, c, address + length - delta, (uint32_t)delta, (uint8_t*)data + length - delta);
1088  if (!NT_SUCCESS(Status)) {
1089  ERR("add_partial_stripe returned %08lx\n", Status);
1090  goto exit;
1091  }
1092 
1093  length -= (uint32_t)delta;
1094  }
1095 
1096  if (length > 0 && (address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) {
1097  uint64_t delta = (num_data_stripes * c->chunk_item->stripe_length) - ((address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length));
1098 
1099  Status = add_partial_stripe(Vcb, c, address, (uint32_t)delta, data);
1100  if (!NT_SUCCESS(Status)) {
1101  ERR("add_partial_stripe returned %08lx\n", Status);
1102  goto exit;
1103  }
1104 
1105  address += delta;
1106  length -= (uint32_t)delta;
1107  irp_offset += delta;
1108  data = (uint8_t*)data + delta;
1109  }
1110 
1111  if (length == 0) {
1113  goto exit;
1114  }
1115 
1116  get_raid0_offset(address - c->offset, c->chunk_item->stripe_length, num_data_stripes, &startoff, &startoffstripe);
1117  get_raid0_offset(address + length - c->offset - 1, c->chunk_item->stripe_length, num_data_stripes, &endoff, &endoffstripe);
1118 
1119  pos = 0;
1120  while (pos < length) {
1121  parity = (((address - c->offset + pos) / (num_data_stripes * c->chunk_item->stripe_length)) + num_data_stripes) % c->chunk_item->num_stripes;
1122 
1123  if (pos == 0) {
1124  uint16_t stripe = (parity + startoffstripe + 1) % c->chunk_item->num_stripes;
1125  ULONG skip, writelen;
1126 
1127  i = startoffstripe;
1128  while (stripe != parity) {
1129  if (i == startoffstripe) {
1130  writelen = (ULONG)min(length, c->chunk_item->stripe_length - (startoff % c->chunk_item->stripe_length));
1131 
1132  stripes[stripe].start = startoff;
1133  stripes[stripe].end = startoff + writelen;
1134 
1135  pos += writelen;
1136 
1137  if (pos == length)
1138  break;
1139  } else {
1140  writelen = (ULONG)min(length - pos, c->chunk_item->stripe_length);
1141 
1142  stripes[stripe].start = startoff - (startoff % c->chunk_item->stripe_length);
1143  stripes[stripe].end = stripes[stripe].start + writelen;
1144 
1145  pos += writelen;
1146 
1147  if (pos == length)
1148  break;
1149  }
1150 
1151  i++;
1152  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1153  }
1154 
1155  if (pos == length)
1156  break;
1157 
1158  for (i = 0; i < startoffstripe; i++) {
1159  stripe = (parity + i + 1) % c->chunk_item->num_stripes;
1160 
1161  stripes[stripe].start = stripes[stripe].end = startoff - (startoff % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
1162  }
1163 
1164  stripes[parity].start = stripes[parity].end = startoff - (startoff % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
1165 
1166  if (length - pos > c->chunk_item->num_stripes * num_data_stripes * c->chunk_item->stripe_length) {
1167  skip = (ULONG)(((length - pos) / (c->chunk_item->num_stripes * num_data_stripes * c->chunk_item->stripe_length)) - 1);
1168 
1169  for (i = 0; i < c->chunk_item->num_stripes; i++) {
1170  stripes[i].end += skip * c->chunk_item->num_stripes * c->chunk_item->stripe_length;
1171  }
1172 
1173  pos += skip * num_data_stripes * c->chunk_item->num_stripes * c->chunk_item->stripe_length;
1174  }
1175  } else if (length - pos >= c->chunk_item->stripe_length * num_data_stripes) {
1176  for (i = 0; i < c->chunk_item->num_stripes; i++) {
1177  stripes[i].end += c->chunk_item->stripe_length;
1178  }
1179 
1180  pos += c->chunk_item->stripe_length * num_data_stripes;
1181  } else {
1182  uint16_t stripe = (parity + 1) % c->chunk_item->num_stripes;
1183 
1184  i = 0;
1185  while (stripe != parity) {
1186  if (endoffstripe == i) {
1187  stripes[stripe].end = endoff + 1;
1188  break;
1189  } else if (endoffstripe > i)
1190  stripes[stripe].end = endoff - (endoff % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
1191 
1192  i++;
1193  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1194  }
1195 
1196  break;
1197  }
1198  }
1199 
1200  parity_start = 0xffffffffffffffff;
1201  parity_end = 0;
1202 
1203  for (i = 0; i < c->chunk_item->num_stripes; i++) {
1204  if (stripes[i].start != 0 || stripes[i].end != 0) {
1205  parity_start = min(stripes[i].start, parity_start);
1206  parity_end = max(stripes[i].end, parity_end);
1207  }
1208  }
1209 
1210  if (parity_end == parity_start) {
1212  goto exit;
1213  }
1214 
1215  parity = (((address - c->offset) / (num_data_stripes * c->chunk_item->stripe_length)) + num_data_stripes) % c->chunk_item->num_stripes;
1216  stripes[parity].start = parity_start;
1217 
1218  parity = (((address - c->offset + length - 1) / (num_data_stripes * c->chunk_item->stripe_length)) + num_data_stripes) % c->chunk_item->num_stripes;
1219  stripes[parity].end = parity_end;
1220 
1221  log_stripes = ExAllocatePoolWithTag(NonPagedPool, sizeof(log_stripe) * num_data_stripes, ALLOC_TAG);
1222  if (!log_stripes) {
1223  ERR("out of memory\n");
1225  goto exit;
1226  }
1227 
1228  RtlZeroMemory(log_stripes, sizeof(log_stripe) * num_data_stripes);
1229 
1230  for (i = 0; i < num_data_stripes; i++) {
1231  log_stripes[i].mdl = IoAllocateMdl(NULL, (ULONG)(parity_end - parity_start), false, false, NULL);
1232  if (!log_stripes[i].mdl) {
1233  ERR("out of memory\n");
1235  goto exit;
1236  }
1237 
1238  log_stripes[i].mdl->MdlFlags |= MDL_PARTIAL;
1239  log_stripes[i].pfns = (PFN_NUMBER*)(log_stripes[i].mdl + 1);
1240  }
1241 
1242  wtc->parity1 = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(parity_end - parity_start), ALLOC_TAG);
1243  if (!wtc->parity1) {
1244  ERR("out of memory\n");
1246  goto exit;
1247  }
1248 
1249  wtc->parity1_mdl = IoAllocateMdl(wtc->parity1, (ULONG)(parity_end - parity_start), false, false, NULL);
1250  if (!wtc->parity1_mdl) {
1251  ERR("out of memory\n");
1253  goto exit;
1254  }
1255 
1256  MmBuildMdlForNonPagedPool(wtc->parity1_mdl);
1257 
1258  if (file_write)
1259  master_mdl = Irp->MdlAddress;
1260  else if (((ULONG_PTR)data % PAGE_SIZE) != 0) {
1262  if (!wtc->scratch) {
1263  ERR("out of memory\n");
1265  goto exit;
1266  }
1267 
1268  RtlCopyMemory(wtc->scratch, data, length);
1269 
1270  master_mdl = IoAllocateMdl(wtc->scratch, length, false, false, NULL);
1271  if (!master_mdl) {
1272  ERR("out of memory\n");
1274  goto exit;
1275  }
1276 
1277  MmBuildMdlForNonPagedPool(master_mdl);
1278 
1279  wtc->mdl = master_mdl;
1280  } else {
1281  master_mdl = IoAllocateMdl(data, length, false, false, NULL);
1282  if (!master_mdl) {
1283  ERR("out of memory\n");
1285  goto exit;
1286  }
1287 
1289 
1290  _SEH2_TRY {
1294  } _SEH2_END;
1295 
1296  if (!NT_SUCCESS(Status)) {
1297  ERR("MmProbeAndLockPages threw exception %08lx\n", Status);
1298  IoFreeMdl(master_mdl);
1299  return Status;
1300  }
1301 
1302  wtc->mdl = master_mdl;
1303  }
1304 
1305  pfns = (PFN_NUMBER*)(master_mdl + 1);
1306  parity_pfns = (PFN_NUMBER*)(wtc->parity1_mdl + 1);
1307 
1308  if (file_write)
1309  pfns = &pfns[irp_offset >> PAGE_SHIFT];
1310 
1311  for (i = 0; i < c->chunk_item->num_stripes; i++) {
1312  if (stripes[i].start != stripes[i].end) {
1313  stripes[i].mdl = IoAllocateMdl((uint8_t*)MmGetMdlVirtualAddress(master_mdl) + irp_offset, (ULONG)(stripes[i].end - stripes[i].start), false, false, NULL);
1314  if (!stripes[i].mdl) {
1315  ERR("IoAllocateMdl failed\n");
1317  goto exit;
1318  }
1319  }
1320  }
1321 
1322  stripeoff = ExAllocatePoolWithTag(PagedPool, sizeof(uint64_t) * c->chunk_item->num_stripes, ALLOC_TAG);
1323  if (!stripeoff) {
1324  ERR("out of memory\n");
1326  goto exit;
1327  }
1328 
1329  RtlZeroMemory(stripeoff, sizeof(uint64_t) * c->chunk_item->num_stripes);
1330 
1331  pos = 0;
1332  parity_pos = 0;
1333 
1334  while (pos < length) {
1335  PFN_NUMBER* stripe_pfns;
1336 
1337  parity = (((address - c->offset + pos) / (num_data_stripes * c->chunk_item->stripe_length)) + num_data_stripes) % c->chunk_item->num_stripes;
1338 
1339  if (pos == 0) {
1340  uint16_t stripe = (parity + startoffstripe + 1) % c->chunk_item->num_stripes;
1341  uint32_t writelen = (uint32_t)min(length - pos, min(stripes[stripe].end - stripes[stripe].start,
1342  c->chunk_item->stripe_length - (stripes[stripe].start % c->chunk_item->stripe_length)));
1343  uint32_t maxwritelen = writelen;
1344 
1345  stripe_pfns = (PFN_NUMBER*)(stripes[stripe].mdl + 1);
1346 
1347  RtlCopyMemory(stripe_pfns, pfns, writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1348 
1349  RtlCopyMemory(log_stripes[startoffstripe].pfns, pfns, writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1350  log_stripes[startoffstripe].pfns += writelen >> PAGE_SHIFT;
1351 
1352  stripeoff[stripe] = writelen;
1353  pos += writelen;
1354 
1355  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1356  i = startoffstripe + 1;
1357 
1358  while (stripe != parity) {
1359  stripe_pfns = (PFN_NUMBER*)(stripes[stripe].mdl + 1);
1360  writelen = (uint32_t)min(length - pos, min(stripes[stripe].end - stripes[stripe].start, c->chunk_item->stripe_length));
1361 
1362  if (writelen == 0)
1363  break;
1364 
1365  if (writelen > maxwritelen)
1366  maxwritelen = writelen;
1367 
1368  RtlCopyMemory(stripe_pfns, &pfns[pos >> PAGE_SHIFT], writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1369 
1370  RtlCopyMemory(log_stripes[i].pfns, &pfns[pos >> PAGE_SHIFT], writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1371  log_stripes[i].pfns += writelen >> PAGE_SHIFT;
1372 
1373  stripeoff[stripe] = writelen;
1374  pos += writelen;
1375 
1376  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1377  i++;
1378  }
1379 
1380  stripe_pfns = (PFN_NUMBER*)(stripes[parity].mdl + 1);
1381 
1382  RtlCopyMemory(stripe_pfns, parity_pfns, maxwritelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1383  stripeoff[parity] = maxwritelen;
1384  parity_pos = maxwritelen;
1385  } else if (length - pos >= c->chunk_item->stripe_length * num_data_stripes) {
1386  uint16_t stripe = (parity + 1) % c->chunk_item->num_stripes;
1387 
1388  i = 0;
1389  while (stripe != parity) {
1390  stripe_pfns = (PFN_NUMBER*)(stripes[stripe].mdl + 1);
1391 
1392  RtlCopyMemory(&stripe_pfns[stripeoff[stripe] >> PAGE_SHIFT], &pfns[pos >> PAGE_SHIFT], (ULONG)(c->chunk_item->stripe_length * sizeof(PFN_NUMBER) >> PAGE_SHIFT));
1393 
1394  RtlCopyMemory(log_stripes[i].pfns, &pfns[pos >> PAGE_SHIFT], (ULONG)(c->chunk_item->stripe_length * sizeof(PFN_NUMBER) >> PAGE_SHIFT));
1395  log_stripes[i].pfns += c->chunk_item->stripe_length >> PAGE_SHIFT;
1396 
1397  stripeoff[stripe] += c->chunk_item->stripe_length;
1398  pos += c->chunk_item->stripe_length;
1399 
1400  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1401  i++;
1402  }
1403 
1404  stripe_pfns = (PFN_NUMBER*)(stripes[parity].mdl + 1);
1405 
1406  RtlCopyMemory(&stripe_pfns[stripeoff[parity] >> PAGE_SHIFT], &parity_pfns[parity_pos >> PAGE_SHIFT], (ULONG)(c->chunk_item->stripe_length * sizeof(PFN_NUMBER) >> PAGE_SHIFT));
1407  stripeoff[parity] += c->chunk_item->stripe_length;
1408  parity_pos += c->chunk_item->stripe_length;
1409  } else {
1410  uint16_t stripe = (parity + 1) % c->chunk_item->num_stripes;
1411  uint32_t writelen, maxwritelen = 0;
1412 
1413  i = 0;
1414  while (pos < length) {
1415  stripe_pfns = (PFN_NUMBER*)(stripes[stripe].mdl + 1);
1416  writelen = (uint32_t)min(length - pos, min(stripes[stripe].end - stripes[stripe].start, c->chunk_item->stripe_length));
1417 
1418  if (writelen == 0)
1419  break;
1420 
1421  if (writelen > maxwritelen)
1422  maxwritelen = writelen;
1423 
1424  RtlCopyMemory(&stripe_pfns[stripeoff[stripe] >> PAGE_SHIFT], &pfns[pos >> PAGE_SHIFT], writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1425 
1426  RtlCopyMemory(log_stripes[i].pfns, &pfns[pos >> PAGE_SHIFT], writelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1427  log_stripes[i].pfns += writelen >> PAGE_SHIFT;
1428 
1429  stripeoff[stripe] += writelen;
1430  pos += writelen;
1431 
1432  stripe = (stripe + 1) % c->chunk_item->num_stripes;
1433  i++;
1434  }
1435 
1436  stripe_pfns = (PFN_NUMBER*)(stripes[parity].mdl + 1);
1437 
1438  RtlCopyMemory(&stripe_pfns[stripeoff[parity] >> PAGE_SHIFT], &parity_pfns[parity_pos >> PAGE_SHIFT], maxwritelen * sizeof(PFN_NUMBER) >> PAGE_SHIFT);
1439  }
1440  }
1441 
1442  for (i = 0; i < num_data_stripes; i++) {
1444 
1445  if (i == 0)
1446  RtlCopyMemory(wtc->parity1, ss, (uint32_t)(parity_end - parity_start));
1447  else
1448  do_xor(wtc->parity1, ss, (uint32_t)(parity_end - parity_start));
1449  }
1450 
1452 
1453 exit:
1454  if (log_stripes) {
1455  for (i = 0; i < num_data_stripes; i++) {
1456  if (log_stripes[i].mdl)
1457  IoFreeMdl(log_stripes[i].mdl);
1458  }
1459 
1460  ExFreePool(log_stripes);
1461  }
1462 
1463  if (stripeoff)
1464  ExFreePool(stripeoff);
1465 
1466  return Status;
1467 }
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define max(a, b)
Definition: svc.c:63
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MmGetMdlVirtualAddress(_Mdl)
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
LONG NTSTATUS
Definition: precomp.h:26
Definition: write.c:113
unsigned short int uint16_t
Definition: acefiex.h:54
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
_Post_satisfies_ static stripe __inline void get_raid0_offset(_In_ uint64_t off, _In_ uint64_t stripe_length, _In_ uint16_t num_stripes, _Out_ uint64_t *stripeoff, _Out_ uint16_t *stripe)
Definition: btrfs_drv.h:989
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ALLOC_TAG
Definition: btrfs_drv.h:87
ULONG PFN_NUMBER
Definition: ke.h:9
_In_ PIRP Irp
Definition: csq.h:116
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
WDF_INTERRUPT_PRIORITY priority
PFN_NUMBER * pfns
Definition: write.c:1067
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BYTE uint8_t
Definition: msvideo1.c:66
MDL * mdl
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define ERR(fmt,...)
Definition: debug.h:110
_SEH2_END
Definition: create.c:4400
UINT64 uint64_t
Definition: types.h:77
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
xor_func do_xor
Definition: btrfs.c:126
GLuint start
Definition: gl.h:1545
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
#define skip(...)
Definition: atltest.h:64
#define MDL_PARTIAL
Definition: mmtypes.h:22
PMDL mdl
Definition: write.c:1066
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ss
Definition: i386-dis.c:442
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
void exit(int exitcode)
Definition: _exit.c:33
#define uint32_t
Definition: nsiface.idl:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ __attribute__() [7/18]

__attribute__ ( (nonnull(1, 3, 5))  )

Definition at line 1908 of file write.c.

1910  {
1911  NTSTATUS Status;
1912  uint32_t i;
1913  CHUNK_ITEM_STRIPE* cis;
1914  write_stripe* stripes = NULL;
1915  uint64_t total_writing = 0;
1916  ULONG allowed_missing, missing;
1917 
1918  TRACE("(%p, %I64x, %p, %x)\n", Vcb, address, data, length);
1919 
1920  if (!c) {
1922  if (!c) {
1923  ERR("could not get chunk for address %I64x\n", address);
1924  return STATUS_INTERNAL_ERROR;
1925  }
1926  }
1927 
1928  stripes = ExAllocatePoolWithTag(PagedPool, sizeof(write_stripe) * c->chunk_item->num_stripes, ALLOC_TAG);
1929  if (!stripes) {
1930  ERR("out of memory\n");
1932  }
1933 
1934  RtlZeroMemory(stripes, sizeof(write_stripe) * c->chunk_item->num_stripes);
1935 
1936  cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
1937 
1938  if (c->chunk_item->type & BLOCK_FLAG_RAID0) {
1939  Status = prepare_raid0_write(c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, wtc);
1940  if (!NT_SUCCESS(Status)) {
1941  ERR("prepare_raid0_write returned %08lx\n", Status);
1942  goto prepare_failed;
1943  }
1944 
1945  allowed_missing = 0;
1946  } else if (c->chunk_item->type & BLOCK_FLAG_RAID10) {
1947  Status = prepare_raid10_write(c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, wtc);
1948  if (!NT_SUCCESS(Status)) {
1949  ERR("prepare_raid10_write returned %08lx\n", Status);
1950  goto prepare_failed;
1951  }
1952 
1953  allowed_missing = 1;
1954  } else if (c->chunk_item->type & BLOCK_FLAG_RAID5) {
1955  Status = prepare_raid5_write(Vcb, c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, priority, wtc);
1956  if (!NT_SUCCESS(Status)) {
1957  ERR("prepare_raid5_write returned %08lx\n", Status);
1958  goto prepare_failed;
1959  }
1960 
1961  allowed_missing = 1;
1962  } else if (c->chunk_item->type & BLOCK_FLAG_RAID6) {
1963  Status = prepare_raid6_write(Vcb, c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, priority, wtc);
1964  if (!NT_SUCCESS(Status)) {
1965  ERR("prepare_raid6_write returned %08lx\n", Status);
1966  goto prepare_failed;
1967  }
1968 
1969  allowed_missing = 2;
1970  } else { // write same data to every location - SINGLE, DUP, RAID1, RAID1C3, RAID1C4
1971  for (i = 0; i < c->chunk_item->num_stripes; i++) {
1972  stripes[i].start = address - c->offset;
1973  stripes[i].end = stripes[i].start + length;
1974  stripes[i].data = data;
1975  stripes[i].irp_offset = irp_offset;
1976 
1977  if (c->devices[i]->devobj) {
1978  if (file_write) {
1979  uint8_t* va;
1980  ULONG writelen = (ULONG)(stripes[i].end - stripes[i].start);
1981 
1982  va = (uint8_t*)MmGetMdlVirtualAddress(Irp->MdlAddress) + stripes[i].irp_offset;
1983 
1984  stripes[i].mdl = IoAllocateMdl(va, writelen, false, false, NULL);
1985  if (!stripes[i].mdl) {
1986  ERR("IoAllocateMdl failed\n");
1988  goto prepare_failed;
1989  }
1990 
1991  IoBuildPartialMdl(Irp->MdlAddress, stripes[i].mdl, va, writelen);
1992  } else {
1993  stripes[i].mdl = IoAllocateMdl(stripes[i].data, (ULONG)(stripes[i].end - stripes[i].start), false, false, NULL);
1994  if (!stripes[i].mdl) {
1995  ERR("IoAllocateMdl failed\n");
1997  goto prepare_failed;
1998  }
1999 
2001 
2002  _SEH2_TRY {
2006  } _SEH2_END;
2007 
2008  if (!NT_SUCCESS(Status)) {
2009  ERR("MmProbeAndLockPages threw exception %08lx\n", Status);
2010  IoFreeMdl(stripes[i].mdl);
2011  stripes[i].mdl = NULL;
2012  goto prepare_failed;
2013  }
2014  }
2015  }
2016  }
2017 
2018  allowed_missing = c->chunk_item->num_stripes - 1;
2019  }
2020 
2021  missing = 0;
2022  for (i = 0; i < c->chunk_item->num_stripes; i++) {
2023  if (!c->devices[i]->devobj)
2024  missing++;
2025  }
2026 
2027  if (missing > allowed_missing) {
2028  ERR("cannot write as %lu missing devices (maximum %lu)\n", missing, allowed_missing);
2030  goto prepare_failed;
2031  }
2032 
2033  for (i = 0; i < c->chunk_item->num_stripes; i++) {
2036 
2038  if (!stripe) {
2039  ERR("out of memory\n");
2041  goto end;
2042  }
2043 
2044  if (stripes[i].start == stripes[i].end || !c->devices[i]->devobj) {
2045  stripe->status = WriteDataStatus_Ignore;
2046  stripe->Irp = NULL;
2047  stripe->buf = stripes[i].data;
2048  stripe->mdl = NULL;
2049  } else {
2050  stripe->context = (struct _write_data_context*)wtc;
2051  stripe->buf = stripes[i].data;
2052  stripe->device = c->devices[i];
2053  RtlZeroMemory(&stripe->iosb, sizeof(IO_STATUS_BLOCK));
2054  stripe->status = WriteDataStatus_Pending;
2055  stripe->mdl = stripes[i].mdl;
2056 
2057  if (!Irp) {
2058  stripe->Irp = IoAllocateIrp(stripe->device->devobj->StackSize, false);
2059 
2060  if (!stripe->Irp) {
2061  ERR("IoAllocateIrp failed\n");
2062  ExFreePool(stripe);
2064  goto end;
2065  }
2066  } else {
2068 
2069  if (!stripe->Irp) {
2070  ERR("IoMakeAssociatedIrp failed\n");
2071  ExFreePool(stripe);
2073  goto end;
2074  }
2075  }
2076 
2080 
2082  stripe->Irp->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(stripes[i].mdl, priority);
2083 
2084  stripe->Irp->Flags = IRP_BUFFERED_IO;
2085  } else if (stripe->device->devobj->Flags & DO_DIRECT_IO)
2086  stripe->Irp->MdlAddress = stripe->mdl;
2087  else
2088  stripe->Irp->UserBuffer = MmGetSystemAddressForMdlSafe(stripes[i].mdl, priority);
2089 
2090 #ifdef DEBUG_PARANOID
2091  if (stripes[i].end < stripes[i].start) {
2092  ERR("trying to write stripe with negative length (%I64x < %I64x)\n", stripes[i].end, stripes[i].start);
2093  int3;
2094  }
2095 #endif
2096 
2097  IrpSp->Parameters.Write.Length = (ULONG)(stripes[i].end - stripes[i].start);
2098  IrpSp->Parameters.Write.ByteOffset.QuadPart = stripes[i].start + cis[i].offset;
2099 
2100  total_writing += IrpSp->Parameters.Write.Length;
2101 
2102  stripe->Irp->UserIosb = &stripe->iosb;
2103  wtc->stripes_left++;
2104 
2105  IoSetCompletionRoutine(stripe->Irp, write_data_completion, stripe, true, true, true);
2106  }
2107 
2108  InsertTailList(&wtc->stripes, &stripe->list_entry);
2109  }
2110 
2111  if (diskacc)
2112  fFsRtlUpdateDiskCounters(0, total_writing);
2113 
2115 
2116 end:
2117 
2118  if (stripes) ExFreePool(stripes);
2119 
2120  if (!NT_SUCCESS(Status))
2122 
2123  return Status;
2124 
2125 prepare_failed:
2126  for (i = 0; i < c->chunk_item->num_stripes; i++) {
2127  if (stripes[i].mdl && (i == 0 || stripes[i].mdl != stripes[i-1].mdl)) {
2128  if (stripes[i].mdl->MdlFlags & MDL_PAGES_LOCKED)
2130 
2131  IoFreeMdl(stripes[i].mdl);
2132  }
2133  }
2134 
2135  if (wtc->parity1_mdl) {
2136  if (wtc->parity1_mdl->MdlFlags & MDL_PAGES_LOCKED)
2137  MmUnlockPages(wtc->parity1_mdl);
2138 
2139  IoFreeMdl(wtc->parity1_mdl);
2140  wtc->parity1_mdl = NULL;
2141  }
2142 
2143  if (wtc->parity2_mdl) {
2144  if (wtc->parity2_mdl->MdlFlags & MDL_PAGES_LOCKED)
2145  MmUnlockPages(wtc->parity2_mdl);
2146 
2147  IoFreeMdl(wtc->parity2_mdl);
2148  wtc->parity2_mdl = NULL;
2149  }
2150 
2151  if (wtc->mdl) {
2152  if (wtc->mdl->MdlFlags & MDL_PAGES_LOCKED)
2153  MmUnlockPages(wtc->mdl);
2154 
2155  IoFreeMdl(wtc->mdl);
2156  wtc->mdl = NULL;
2157  }
2158 
2159  if (wtc->parity1) {
2160  ExFreePool(wtc->parity1);
2161  wtc->parity1 = NULL;
2162  }
2163 
2164  if (wtc->parity2) {
2165  ExFreePool(wtc->parity2);
2166  wtc->parity2 = NULL;
2167  }
2168 
2169  if (wtc->scratch) {
2170  ExFreePool(wtc->scratch);
2171  wtc->scratch = NULL;
2172  }
2173 
2175  return Status;
2176 }
PMDL mdl
Definition: write.c:24
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PFILE_OBJECT fileobj
Definition: btrfs_drv.h:519
#define MmGetMdlVirtualAddress(_Mdl)
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:518
LONG NTSTATUS
Definition: precomp.h:26
#define int3
Definition: btrfs_drv.h:1735
Definition: write.c:113
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define InsertTailList(ListHead, Entry)
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
bool diskacc
Definition: btrfs.c:100
uint64_t start
Definition: write.c:21
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
_SEH2_TRY
Definition: create.c:4226
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:87
uint64_t offset
Definition: btrfs.h:353
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
_In_ PIRP Irp
Definition: csq.h:116
uint64_t irp_offset
Definition: write.c:25
uint64_t end
Definition: write.c:22
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
uint8_t * data
Definition: write.c:23
WDF_INTERRUPT_PRIORITY priority
tFsRtlUpdateDiskCounters fFsRtlUpdateDiskCounters
Definition: btrfs.c:93
#define BLOCK_FLAG_RAID10
Definition: shellext.h:81
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1925
Status
Definition: gdiplustypes.h:24
#define BLOCK_FLAG_RAID0
Definition: shellext.h:78
#define TRACE(s)
Definition: solgame.cpp:4
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
#define BLOCK_FLAG_RAID6
Definition: shellext.h:83
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
BYTE uint8_t
Definition: msvideo1.c:66
MDL * mdl
NTSTATUS NTSTATUS NTSTATUS void free_write_data_stripes(write_data_context *wtc) __attribute__((nonnull(1)))
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define ERR(fmt,...)
Definition: debug.h:110
device * device
Definition: write.c:115
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
_SEH2_END
Definition: create.c:4400
UINT64 uint64_t
Definition: types.h:77
#define IRP_BUFFERED_IO
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLuint start
Definition: gl.h:1545
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
LIST_ENTRY stripes
Definition: btrfs_drv.h:930
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define BLOCK_FLAG_RAID5
Definition: shellext.h:82
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS chunk * get_chunk_from_address(device_extension *Vcb, uint64_t address) __attribute__((nonnull(1)))
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70

◆ __attribute__() [8/18]

__attribute__ ( (nonnull(1, 4, 5))  )

Definition at line 2178 of file write.c.

2179  {
2180  uint64_t startoff, endoff;
2181  uint16_t startoffstripe, endoffstripe, datastripes;
2182 
2183  datastripes = c->chunk_item->num_stripes - (c->chunk_item->type & BLOCK_FLAG_RAID5 ? 1 : 2);
2184 
2185  get_raid0_offset(address - c->offset, c->chunk_item->stripe_length, datastripes, &startoff, &startoffstripe);
2186  get_raid0_offset(address + length - c->offset - 1, c->chunk_item->stripe_length, datastripes, &endoff, &endoffstripe);
2187 
2188  startoff -= startoff % c->chunk_item->stripe_length;
2189  endoff = sector_align(endoff, c->chunk_item->stripe_length);
2190 
2191  *lockaddr = c->offset + (startoff * datastripes);
2192  *locklen = (endoff - startoff) * datastripes;
2193 }
unsigned short int uint16_t
Definition: acefiex.h:54
_Post_satisfies_ static stripe __inline void get_raid0_offset(_In_ uint64_t off, _In_ uint64_t stripe_length, _In_ uint16_t num_stripes, _Out_ uint64_t *stripeoff, _Out_ uint16_t *stripe)
Definition: btrfs_drv.h:989
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
const GLubyte * c
Definition: glext.h:8905
GLuint address
Definition: glext.h:9393
UINT64 uint64_t
Definition: types.h:77
#define BLOCK_FLAG_RAID5
Definition: shellext.h:82
static uint64_t __inline sector_align(uint64_t n, uint64_t a)

◆ __attribute__() [9/18]

__attribute__ ( (nonnull(2, 3))  )

Definition at line 2278 of file write.c.

2280  {
2281  write_data_stripe* stripe = conptr;
2283  LIST_ENTRY* le;
2284 
2286 
2287  // FIXME - we need a lock here
2288 
2289  if (stripe->status == WriteDataStatus_Cancelling) {
2291  goto end;
2292  }
2293 
2294  stripe->iosb = Irp->IoStatus;
2295 
2296  if (NT_SUCCESS(Irp->IoStatus.Status)) {
2297  stripe->status = WriteDataStatus_Success;
2298  } else {
2299  le = context->stripes.Flink;
2300 
2301  stripe->status = WriteDataStatus_Error;
2302 
2303  while (le != &context->stripes) {
2305 
2306  if (s2->status == WriteDataStatus_Pending) {
2307  s2->status = WriteDataStatus_Cancelling;
2308  IoCancelIrp(s2->Irp);
2309  }
2310 
2311  le = le->Flink;
2312  }
2313  }
2314 
2315 end:
2316  if (InterlockedDecrement(&context->stripes_left) == 0)
2317  KeSetEvent(&context->Event, 0, false);
2318 
2320 }
struct S2 s2
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7251
Definition: write.c:113
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define UNUSED(x)
Definition: btrfs_drv.h:82
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLuint GLuint end
Definition: gl.h:1545
#define InterlockedDecrement
Definition: armddk.h:52
Definition: typedefs.h:119
Definition: list.h:27
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101

◆ __attribute__() [10/18]

__attribute__ ( (nonnull(1, 2, 3))  )

Definition at line 2383 of file write.c.

2384  {
2385  LIST_ENTRY* le = prevextle->Flink;
2386 
2387  while (le != &fcb->extents) {
2389 
2390  if (ext->offset >= newext->offset) {
2391  InsertHeadList(ext->list_entry.Blink, &newext->list_entry);
2392  return;
2393  }
2394 
2395  le = le->Flink;
2396  }
2397 
2398  InsertTailList(&fcb->extents, &newext->list_entry);
2399 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define InsertTailList(ListHead, Entry)
char ext[3]
Definition: mkdosfs.c:358
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY extents
Definition: btrfs_drv.h:300
Definition: typedefs.h:119
Definition: list.h:27

◆ __attribute__() [11/18]

__attribute__ ( (nonnull(1, 2, 6))  )

Definition at line 2401 of file write.c.

2402  {
2403  NTSTATUS Status;
2404  LIST_ENTRY* le;
2405 
2406  le = fcb->extents.Flink;
2407 
2408  while (le != &fcb->extents) {
2409  LIST_ENTRY* le2 = le->Flink;
2411 
2412  if (!ext->ignore) {
2413  EXTENT_DATA* ed = &ext->extent_data;
2414  uint64_t len;
2415 
2416  if (ed->type == EXTENT_TYPE_INLINE)
2417  len = ed->decoded_size;
2418  else
2419  len = ((EXTENT_DATA2*)ed->data)->num_bytes;
2420 
2421  if (ext->offset < end_data && ext->offset + len > start_data) {
2422  if (ed->type == EXTENT_TYPE_INLINE) {
2423  if (start_data <= ext->offset && end_data >= ext->offset + len) { // remove all
2424  remove_fcb_extent(fcb, ext, rollback);
2425 
2427  fcb->inode_item_changed = true;
2428  } else {
2429  ERR("trying to split inline extent\n");
2430 #ifdef DEBUG_PARANOID
2431  int3;
2432 #endif
2433  return STATUS_INTERNAL_ERROR;
2434  }
2435  } else {
2436  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ed->data;
2437 
2438  if (start_data <= ext->offset && end_data >= ext->offset + len) { // remove all
2439  if (ed2->size != 0) {
2440  chunk* c;
2441 
2443  fcb->inode_item_changed = true;
2444 
2446 
2447  if (!c) {
2448  ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
2449  } else {
2450  Status = update_changed_extent_ref(Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1,
2452  if (!NT_SUCCESS(Status)) {
2453  ERR("update_changed_extent_ref returned %08lx\n", Status);
2454  goto end;
2455  }
2456  }
2457  }
2458 
2459  remove_fcb_extent(fcb, ext, rollback);
2460  } else if (start_data <= ext->offset && end_data < ext->offset + len) { // remove beginning
2461  EXTENT_DATA2* ned2;
2462  extent* newext;
2463 
2464  if (ed2->size != 0) {
2465  fcb->inode_item.st_blocks -= end_data - ext->offset;
2466  fcb->inode_item_changed = true;
2467  }
2468 
2469  newext = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2), ALLOC_TAG);
2470  if (!newext) {
2471  ERR("out of memory\n");
2473  goto end;
2474  }
2475 
2476  ned2 = (EXTENT_DATA2*)newext->extent_data.data;
2477 
2478  newext->extent_data.generation = Vcb->superblock.generation;
2479  newext->extent_data.decoded_size = ed->decoded_size;
2480  newext->extent_data.compression = ed->compression;
2481  newext->extent_data.encryption = ed->encryption;
2482  newext->extent_data.encoding = ed->encoding;
2483  newext->extent_data.type = ed->type;
2484  ned2->address = ed2->address;
2485  ned2->size = ed2->size;
2486  ned2->offset = ed2->offset + (end_data - ext->offset);
2487  ned2->num_bytes = ed2->num_bytes - (end_data - ext->offset);
2488 
2489  newext->offset = end_data;
2490  newext->datalen = sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2);
2491  newext->unique = ext->unique;
2492  newext->ignore = false;
2493  newext->inserted = true;
2494 
2495  if (ext->csum) {
2496  if (ed->compression == BTRFS_COMPRESSION_NONE) {
2497  newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ned2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2498  if (!newext->csum) {
2499  ERR("out of memory\n");
2501  ExFreePool(newext);
2502  goto end;
2503  }
2504 
2505  RtlCopyMemory(newext->csum, (uint8_t*)ext->csum + (((end_data - ext->offset) * Vcb->csum_size) >> Vcb->sector_shift),
2506  (ULONG)((ned2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift));
2507  } else {
2508  newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2509  if (!newext->csum) {
2510  ERR("out of memory\n");
2512  ExFreePool(newext);
2513  goto end;
2514  }
2515 
2516  RtlCopyMemory(newext->csum, ext->csum, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift));
2517  }
2518  } else
2519  newext->csum = NULL;
2520 
2521  add_extent(fcb, &ext->list_entry, newext);
2522 
2523  remove_fcb_extent(fcb, ext, rollback);
2524  } else if (start_data > ext->offset && end_data >= ext->offset + len) { // remove end
2525  EXTENT_DATA2* ned2;
2526  extent* newext;
2527 
2528  if (ed2->size != 0) {
2529  fcb->inode_item.st_blocks -= ext->offset + len - start_data;
2530  fcb->inode_item_changed = true;
2531  }
2532 
2533  newext = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2), ALLOC_TAG);
2534  if (!newext) {
2535  ERR("out of memory\n");
2537  goto end;
2538  }
2539 
2540  ned2 = (EXTENT_DATA2*)newext->extent_data.data;
2541 
2542  newext->extent_data.generation = Vcb->superblock.generation;
2543  newext->extent_data.decoded_size = ed->decoded_size;
2544  newext->extent_data.compression = ed->compression;
2545  newext->extent_data.encryption = ed->encryption;
2546  newext->extent_data.encoding = ed->encoding;
2547  newext->extent_data.type = ed->type;
2548  ned2->address = ed2->address;
2549  ned2->size = ed2->size;
2550  ned2->offset = ed2->offset;
2551  ned2->num_bytes = start_data - ext->offset;
2552 
2553  newext->offset = ext->offset;
2554  newext->datalen = sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2);
2555  newext->unique = ext->unique;
2556  newext->ignore = false;
2557  newext->inserted = true;
2558 
2559  if (ext->csum) {
2560  if (ed->compression == BTRFS_COMPRESSION_NONE) {
2561  newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ned2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2562  if (!newext->csum) {
2563  ERR("out of memory\n");
2565  ExFreePool(newext);
2566  goto end;
2567  }
2568 
2569  RtlCopyMemory(newext->csum, ext->csum, (ULONG)((ned2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift));
2570  } else {
2571  newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2572  if (!newext->csum) {
2573  ERR("out of memory\n");
2575  ExFreePool(newext);
2576  goto end;
2577  }
2578 
2579  RtlCopyMemory(newext->csum, ext->csum, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift));
2580  }
2581  } else
2582  newext->csum = NULL;
2583 
2584  InsertHeadList(&ext->list_entry, &newext->list_entry);
2585 
2586  remove_fcb_extent(fcb, ext, rollback);
2587  } else if (start_data > ext->offset && end_data < ext->offset + len) { // remove middle
2588  EXTENT_DATA2 *neda2, *nedb2;
2589  extent *newext1, *newext2;
2590 
2591  if (ed2->size != 0) {
2592  chunk* c;
2593 
2594  fcb->inode_item.st_blocks -= end_data - start_data;
2595  fcb->inode_item_changed = true;
2596 
2598 
2599  if (!c) {
2600  ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
2601  } else {
2602  Status = update_changed_extent_ref(Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, 1,
2604  if (!NT_SUCCESS(Status)) {
2605  ERR("update_changed_extent_ref returned %08lx\n", Status);
2606  goto end;
2607  }
2608  }
2609  }
2610 
2611  newext1 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2), ALLOC_TAG);
2612  if (!newext1) {
2613  ERR("out of memory\n");
2615  goto end;
2616  }
2617 
2618  newext2 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2), ALLOC_TAG);
2619  if (!newext2) {
2620  ERR("out of memory\n");
2622  ExFreePool(newext1);
2623  goto end;
2624  }
2625 
2626  neda2 = (EXTENT_DATA2*)newext1->extent_data.data;
2627 
2628  newext1->extent_data.generation = Vcb->superblock.generation;
2629  newext1->extent_data.decoded_size = ed->decoded_size;
2630  newext1->extent_data.compression = ed->compression;
2631  newext1->extent_data.encryption = ed->encryption;
2632  newext1->extent_data.encoding = ed->encoding;
2633  newext1->extent_data.type = ed->type;
2634  neda2->address = ed2->address;
2635  neda2->size = ed2->size;
2636  neda2->offset = ed2->offset;
2637  neda2->num_bytes = start_data - ext->offset;
2638 
2639  nedb2 = (EXTENT_DATA2*)newext2->extent_data.data;
2640 
2641  newext2->extent_data.generation = Vcb->superblock.generation;
2642  newext2->extent_data.decoded_size = ed->decoded_size;
2643  newext2->extent_data.compression = ed->compression;
2644  newext2->extent_data.encryption = ed->encryption;
2645  newext2->extent_data.encoding = ed->encoding;
2646  newext2->extent_data.type = ed->type;
2647  nedb2->address = ed2->address;
2648  nedb2->size = ed2->size;
2649  nedb2->offset = ed2->offset + (end_data - ext->offset);
2650  nedb2->num_bytes = ext->offset + len - end_data;
2651 
2652  newext1->offset = ext->offset;
2653  newext1->datalen = sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2);
2654  newext1->unique = ext->unique;
2655  newext1->ignore = false;
2656  newext1->inserted = true;
2657 
2658  newext2->offset = end_data;
2659  newext2->datalen = sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2);
2660  newext2->unique = ext->unique;
2661  newext2->ignore = false;
2662  newext2->inserted = true;
2663 
2664  if (ext->csum) {
2665  if (ed->compression == BTRFS_COMPRESSION_NONE) {
2666  newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((neda2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2667  if (!newext1->csum) {
2668  ERR("out of memory\n");
2670  ExFreePool(newext1);
2671  ExFreePool(newext2);
2672  goto end;
2673  }
2674 
2675  newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((nedb2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2676  if (!newext2->csum) {
2677  ERR("out of memory\n");
2679  ExFreePool(newext1->csum);
2680  ExFreePool(newext1);
2681  ExFreePool(newext2);
2682  goto end;
2683  }
2684 
2685  RtlCopyMemory(newext1->csum, ext->csum, (ULONG)((neda2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift));
2686  RtlCopyMemory(newext2->csum, (uint8_t*)ext->csum + (((end_data - ext->offset) * Vcb->csum_size) >> Vcb->sector_shift),
2687  (ULONG)((nedb2->num_bytes * Vcb->csum_size) >> Vcb->sector_shift));
2688  } else {
2689  newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2690  if (!newext1->csum) {
2691  ERR("out of memory\n");
2693  ExFreePool(newext1);
2694  ExFreePool(newext2);
2695  goto end;
2696  }
2697 
2698  newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift), ALLOC_TAG);
2699  if (!newext2->csum) {
2700  ERR("out of memory\n");
2702  ExFreePool(newext1->csum);
2703  ExFreePool(newext1);
2704  ExFreePool(newext2);
2705  goto end;
2706  }
2707 
2708  RtlCopyMemory(newext1->csum, ext->csum, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift));
2709  RtlCopyMemory(newext2->csum, ext->csum, (ULONG)((ed2->size * Vcb->csum_size) >> Vcb->sector_shift));
2710  }
2711  } else {
2712  newext1->csum = NULL;
2713  newext2->csum = NULL;
2714  }
2715 
2716  InsertHeadList(&ext->list_entry, &newext1->list_entry);
2717  add_extent(fcb, &newext1->list_entry, newext2);
2718 
2719  remove_fcb_extent(fcb, ext, rollback);
2720  }
2721  }
2722  }
2723  }
2724 
2725  le = le2;
2726  }
2727 
2729 
2730 end:
2731  fcb->extents_changed = true;
2733 
2734  return Status;
2735 }
uint64_t generation
Definition: btrfs.h:358
uint8_t type
Definition: btrfs.h:363
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS update_changed_extent_ref(device_extension *Vcb, chunk *c, uint64_t address, uint64_t size, uint64_t root, uint64_t objid, uint64_t offset, int32_t count, bool no_csum, bool superseded, PIRP Irp)
Definition: extent-tree.c:1951
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
uint64_t decoded_size
Definition: btrfs.h:359
LONG NTSTATUS
Definition: precomp.h:26
#define int3
Definition: btrfs_drv.h:1735
void * csum
Definition: btrfs_drv.h:233
LIST_ENTRY list_entry
Definition: btrfs_drv.h:235
uint16_t datalen
Definition: btrfs_drv.h:229
uint32_t flags
Definition: btrfs.h:297
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint8_t encryption
Definition: btrfs.h:361
bool ignore
Definition: btrfs_drv.h:231
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1355
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:87
bool inserted
Definition: btrfs_drv.h:232
#define EXTENT_TYPE_INLINE
Definition: btrfs.h:74
_In_ PIRP Irp
Definition: csq.h:116
uint64_t address
Definition: btrfs.h:368
uint64_t offset
Definition: btrfs_drv.h:228
bool extents_changed
Definition: btrfs_drv.h:323
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
uint64_t size
Definition: btrfs.h:369
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
bool unique
Definition: btrfs_drv.h:230
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
uint16_t encoding
Definition: btrfs.h:362
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:289
GLintptr offset
Definition: glext.h:5920
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
LIST_ENTRY extents
Definition: btrfs_drv.h:300
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t num_bytes
Definition: btrfs.h:371
uint64_t st_blocks
Definition: btrfs.h:290
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t data[1]
Definition: btrfs.h:364
UINT64 uint64_t
Definition: types.h:77
struct _root * subvol
Definition: btrfs_drv.h:288
Definition: list.h:27
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
EXTENT_DATA extent_data
Definition: btrfs_drv.h:237
NTSTATUS bool void NTSTATUS void add_extent(_In_ fcb *fcb, _In_ LIST_ENTRY *prevextle, _In_ __drv_aliasesMem extent *newext) __attribute__((nonnull(1
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint64_t offset
Definition: btrfs.h:370
#define STATUS_SUCCESS
Definition: shellext.h:65
bool inode_item_changed
Definition: btrfs_drv.h:306
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
uint8_t compression
Definition: btrfs.h:360
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS chunk * get_chunk_from_address(device_extension *Vcb, uint64_t address) __attribute__((nonnull(1)))

◆ __attribute__() [12/18]

__attribute__ ( (nonnull(1, 3, 7))  )

Definition at line 2757 of file write.c.

2759  {
2760  extent* ext;
2761  LIST_ENTRY* le;
2762 
2763  ext = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + edsize, ALLOC_TAG);
2764  if (!ext) {
2765  ERR("out of memory\n");
2767  }
2768 
2769  ext->offset = offset;
2770  ext->datalen = edsize;
2771  ext->unique = unique;
2772  ext->ignore = false;
2773  ext->inserted = true;
2774  ext->csum = csum;
2775 
2776  RtlCopyMemory(&ext->extent_data, ed, edsize);
2777 
2778  le = fcb->extents.Flink;
2779  while (le != &fcb->extents) {
2780  extent* oldext = CONTAINING_RECORD(le, extent, list_entry);
2781 
2782  if (oldext->offset >= offset) {
2783  InsertHeadList(le->Blink, &ext->list_entry);
2784  goto end;
2785  }
2786 
2787  le = le->Flink;
2788  }
2789 
2790  InsertTailList(&fcb->extents, &ext->list_entry);
2791 
2792 end:
2793  add_insert_extent_rollback(rollback, fcb, ext);
2794 
2795  return STATUS_SUCCESS;
2796 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define InsertTailList(ListHead, Entry)
#define ALLOC_TAG
Definition: btrfs_drv.h:87
uint64_t offset
Definition: btrfs_drv.h:228
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
GLintptr offset
Definition: glext.h:5920
LIST_ENTRY extents
Definition: btrfs_drv.h:300
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: typedefs.h:119
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:27
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
Definition: ffs.h:52
_ForwardIter unique(_ForwardIter __first, _ForwardIter __last)
Definition: _algo.h:298
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ __attribute__() [13/18]

__attribute__ ( (nonnull(1, 2, 5, 7, 10))  )

Definition at line 2908 of file write.c.

2910  {
2911  bool success = false;
2912  EXTENT_DATA* ed;
2913  EXTENT_DATA2* ed2;
2914  chunk* c;
2915  LIST_ENTRY* le;
2916  extent* ext = NULL;
2917 
2918  le = fcb->extents.Flink;
2919 
2920  while (le != &fcb->extents) {
2921  extent* nextext = CONTAINING_RECORD(le, extent, list_entry);
2922 
2923  if (!nextext->ignore) {
2924  if (nextext->offset == start_data) {
2925  ext = nextext;
2926  break;
2927  } else if (nextext->offset > start_data)
2928  break;
2929 
2930  ext = nextext;
2931  }
2932 
2933  le = le->Flink;
2934  }
2935 
2936  if (!ext)
2937  return false;
2938 
2939  ed = &ext->extent_data;
2940 
2941  if (ed->type != EXTENT_TYPE_REGULAR && ed->type != EXTENT_TYPE_PREALLOC) {
2942  TRACE("not extending extent which is not regular or prealloc\n");
2943  return false;
2944  }
2945 
2946  ed2 = (EXTENT_DATA2*)ed->data;
2947 
2948  if (ext->offset + ed2->num_bytes != start_data) {
2949  TRACE("last EXTENT_DATA does not run up to start_data (%I64x + %I64x != %I64x)\n", ext->offset, ed2->num_bytes, start_data);
2950  return false;
2951  }
2952 
2954 
2955  if (c->reloc || c->readonly || c->chunk_item->type != Vcb->data_flags)
2956  return false;
2957 
2959 
2960  if (length > c->chunk_item->size - c->used) {
2962  return false;
2963  }
2964 
2965  if (!c->cache_loaded) {
2967 
2968  if (!NT_SUCCESS(Status)) {
2969  ERR("load_cache_chunk returned %08lx\n", Status);
2971  return false;
2972  }
2973  }
2974 
2975  le = c->space.Flink;
2976  while (le != &c->space) {
2978 
2979  if (s->address == ed2->address + ed2->size) {
2980  uint64_t newlen = min(min(s->size, length), MAX_EXTENT_SIZE);
2981 
2982  success = insert_extent_chunk(Vcb, fcb, c, start_data, newlen, false, data, Irp, rollback, BTRFS_COMPRESSION_NONE, newlen, file_write, irp_offset);
2983 
2984  if (success)
2985  *written += newlen;
2986  else
2988 
2989  return success;
2990  } else if (s->address > ed2->address + ed2->size)
2991  break;
2992 
2993  le = le->Flink;
2994  }
2995 
2997 
2998  return false;
2999 }
uint8_t type
Definition: btrfs.h:363
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
LONG NTSTATUS
Definition: precomp.h:26
if(dx==0 &&dy==0)
Definition: linetemp.h:174
bool ignore
Definition: btrfs_drv.h:231
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1355
_In_ PIRP Irp
Definition: csq.h:116
uint64_t address
Definition: btrfs.h:368
uint64_t offset
Definition: btrfs_drv.h:228
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
char ext[3]
Definition: mkdosfs.c:358
#define release_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1132
uint64_t size
Definition: btrfs.h:369
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_EXTENT_SIZE
Definition: btrfs_drv.h:111
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
LIST_ENTRY extents
Definition: btrfs_drv.h:300
#define success(from, fromstr, to, tostr)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble s
Definition: gl.h:2039
Definition: typedefs.h:119
#define EXTENT_TYPE_PREALLOC
Definition: btrfs.h:76
uint64_t num_bytes
Definition: btrfs.h:371
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:75
NTSTATUS load_cache_chunk(device_extension *Vcb, chunk *c, PIRP Irp)
Definition: free-space.c:980
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t data[1]
Definition: btrfs.h:364
UINT64 uint64_t
Definition: types.h:77
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1131
bool insert_extent_chunk(_In_ device_extension *Vcb, _In_ fcb *fcb, _In_ chunk *c, _In_ uint64_t start_data, _In_ uint64_t length, _In_ bool prealloc, _In_opt_ void *data, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback, _In_ uint8_t compression, _In_ uint64_t decoded_size, _In_ bool file_write, _In_ uint64_t irp_offset)
Definition: write.c:2824
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
#define c
Definition: ke_i.h:80
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS chunk * get_chunk_from_address(device_extension *Vcb, uint64_t address) __attribute__((nonnull(1)))

◆ __attribute__() [14/18]

__attribute__ ( (nonnull(1, 4))  )

Definition at line 3058 of file write.c.

3059  {
3060  LIST_ENTRY* le;
3061  chunk* c;
3062  uint64_t flags;
3063  NTSTATUS Status;
3064  bool page_file = fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE;
3065 
3066  flags = fcb->Vcb->data_flags;
3067 
3068  do {
3069  uint64_t extlen = min(MAX_EXTENT_SIZE, length);
3070 
3071  ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true);
3072 
3073  le = fcb->Vcb->chunks.Flink;
3074  while (le != &fcb->Vcb->chunks) {
3076 
3077  if (!c->readonly && !c->reloc) {
3079 
3080  if (c->chunk_item->type == flags && (c->chunk_item->size - c->used) >= extlen) {
3081  if (insert_extent_chunk(fcb->Vcb, fcb, c, start, extlen, !page_file, NULL, NULL, rollback, BTRFS_COMPRESSION_NONE, extlen, false, 0)) {
3082  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
3083  goto cont;
3084  }
3085  }
3086 
3088  }
3089 
3090  le = le->Flink;
3091  }
3092 
3093  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
3094 
3095  ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true);
3096 
3097  Status = alloc_chunk(fcb->Vcb, flags, &c, false);
3098 
3099  ExReleaseResourceLite(&fcb->Vcb->chunk_lock);
3100 
3101  if (!NT_SUCCESS(Status)) {
3102  ERR("alloc_chunk returned %08lx\n", Status);
3103  goto end;
3104  }
3105 
3107 
3108  if (c->chunk_item->type == flags && (c->chunk_item->size - c->used) >= extlen) {
3109  if (insert_extent_chunk(fcb->Vcb, fcb, c, start, extlen, !page_file, NULL, NULL, rollback, BTRFS_COMPRESSION_NONE, extlen, false, 0))
3110  goto cont;
3111  }
3112 
3114 
3115  Status = insert_chunk_fragmented(fcb, start, length, NULL, true, rollback);
3116  if (!NT_SUCCESS(Status))
3117  ERR("insert_chunk_fragmented returned %08lx\n", Status);
3118 
3119  goto end;
3120 
3121 cont:
3122  length -= extlen;
3123  start += extlen;
3124  } while (length > 0);
3125 
3127 
3128 end:
3129  return Status;
3130 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
#define FSRTL_FLAG2_IS_PAGING_FILE
Definition: fsrtltypes.h:57
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define release_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1132
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size) __attribute__((nonnull(1
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_EXTENT_SIZE
Definition: btrfs_drv.h:111
const GLubyte * c
Definition: glext.h:8905
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLbitfield flags
Definition: glext.h:7161
GLuint GLuint end
Definition: gl.h:1545
Definition: typedefs.h:119
#define ERR(fmt,...)
Definition: debug.h:110
UINT64 uint64_t
Definition: types.h:77
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1131
GLuint start
Definition: gl.h:1545
bool insert_extent_chunk(_In_ device_extension *Vcb, _In_ fcb *fcb, _In_ chunk *c, _In_ uint64_t start_data, _In_ uint64_t length, _In_ bool prealloc, _In_opt_ void *data, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback, _In_ uint8_t compression, _In_ uint64_t decoded_size, _In_ bool file_write, _In_ uint64_t irp_offset)
Definition: write.c:2824
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define c
Definition: ke_i.h:80
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _device_extension * Vcb
Definition: btrfs_drv.h:287

◆ __attribute__() [15/18]

__attribute__ ( (nonnull(1, 2, 5, 9))  )

Definition at line 3132 of file write.c.

3134  {
3135  NTSTATUS Status;
3136  LIST_ENTRY* le;
3137  chunk* c;
3138  uint64_t flags, orig_length = length, written = 0;
3139 
3140  TRACE("(%p, (%I64x, %I64x), %I64x, %I64x, %p)\n", Vcb, fcb->subvol->id, fcb->inode, start_data, length, data);
3141 
3142  if (start_data > 0) {
3143  try_extend_data(Vcb, fcb, start_data, length, data, Irp, &written, file_write, irp_offset, rollback);
3144 
3145  if (written == length)
3146  return STATUS_SUCCESS;
3147  else if (written > 0) {
3148  start_data += written;
3149  irp_offset += written;
3150  length -= written;
3151  data = &((uint8_t*)data)[written];
3152  }
3153  }
3154 
3155  flags = Vcb->data_flags;
3156 
3157  while (written < orig_length) {
3158  uint64_t newlen = min(length, MAX_EXTENT_SIZE);
3159  bool done = false;
3160 
3161  // Rather than necessarily writing the whole extent at once, we deal with it in blocks of 128 MB.
3162  // First, see if we can write the extent part to an existing chunk.
3163 
3164  ExAcquireResourceSharedLite(&Vcb->chunk_lock, true);
3165 
3166  le = Vcb->chunks.Flink;
3167  while (le != &Vcb->chunks) {
3169 
3170  if (!c->readonly && !c->reloc) {
3172 
3173  if (c->chunk_item->type == flags && (c->chunk_item->size - c->used) >= newlen &&
3174  insert_extent_chunk(Vcb, fcb, c, start_data, newlen, false, data, Irp, rollback, BTRFS_COMPRESSION_NONE, newlen, file_write, irp_offset)) {
3175  written += newlen;
3176 
3177  if (written == orig_length) {
3178  ExReleaseResourceLite(&Vcb->chunk_lock);
3179  return STATUS_SUCCESS;
3180  } else {
3181  done = true;
3182  start_data += newlen;
3183  irp_offset += newlen;
3184  length -= newlen;
3185  data = &((uint8_t*)data)[newlen];
3186  break;
3187  }
3188  } else
3190  }
3191 
3192  le = le->Flink;
3193  }
3194 
3195  ExReleaseResourceLite(&Vcb->chunk_lock);
3196 
3197  if (done) continue;
3198 
3199  // Otherwise, see if we can put it in a new chunk.
3200 
3201  ExAcquireResourceExclusiveLite(&Vcb->chunk_lock, true);
3202 
3203  Status = alloc_chunk(Vcb, flags, &c, false);
3204 
3205  ExReleaseResourceLite(&Vcb->chunk_lock);
3206 
3207  if (!NT_SUCCESS(Status)) {
3208  ERR("alloc_chunk returned %08lx\n", Status);
3209  return Status;
3210  }
3211 
3212  if (c) {
3214 
3215  if (c->chunk_item->type == flags && (c->chunk_item->size - c->used) >= newlen &&
3216  insert_extent_chunk(Vcb, fcb, c, start_data, newlen, false, data, Irp, rollback, BTRFS_COMPRESSION_NONE, newlen, file_write, irp_offset)) {
3217  written += newlen;
3218 
3219  if (written == orig_length)
3220  return STATUS_SUCCESS;
3221  else {
3222  done = true;
3223  start_data += newlen;
3224  irp_offset += newlen;
3225  length -= newlen;
3226  data = &((uint8_t*)data)[newlen];
3227  }
3228  } else
3230  }
3231 
3232  if (!done) {
3233  Status = insert_chunk_fragmented(fcb, start_data, length, data, false, rollback);
3234  if (!NT_SUCCESS(Status))
3235  ERR("insert_chunk_fragmented returned %08lx\n", Status);
3236 
3237  return Status;
3238  }
3239  }
3240 
3241  return STATUS_DISK_FULL;
3242 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
LONG NTSTATUS
Definition: precomp.h:26
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1355
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ PIRP Irp
Definition: csq.h:116
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define release_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1132
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size) __attribute__((nonnull(1
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:289
#define MAX_EXTENT_SIZE
Definition: btrfs_drv.h:111
#define Vcb
Definition: cdprocs.h:1415
const GLubyte * c
Definition: glext.h:8905
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
Definition: typedefs.h:119
BYTE uint8_t
Definition: msvideo1.c:66
#define ERR(fmt,...)
Definition: debug.h:110
UINT64 uint64_t
Definition: types.h:77
#define acquire_chunk_lock(c, Vcb)
Definition: btrfs_drv.h:1131
bool insert_extent_chunk(_In_ device_extension *Vcb, _In_ fcb *fcb, _In_ chunk *c, _In_ uint64_t start_data, _In_ uint64_t length, _In_ bool prealloc, _In_opt_ void *data, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback, _In_ uint8_t compression, _In_ uint64_t decoded_size, _In_ bool file_write, _In_ uint64_t irp_offset)
Definition: write.c:2824
struct _root * subvol
Definition: btrfs_drv.h:288
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define c
Definition: ke_i.h:80
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ __attribute__() [16/18]

__attribute__ ( (nonnull(1, 6))  )

Definition at line 3336 of file write.c.

3337  {
3338  uint64_t oldalloc, newalloc;
3339  bool cur_inline;
3340  NTSTATUS Status;
3341 
3342  TRACE("(%p, %p, %I64x, %u)\n", fcb, fileref, end, prealloc);
3343 
3344  if (fcb->ads) {
3345  if (end > 0xffff)
3346  return STATUS_DISK_FULL;
3347 
3348  return stream_set_end_of_file_information(fcb->Vcb, (uint16_t)end, fcb, fileref, false);
3349  } else {
3350  extent* ext = NULL;
3351  LIST_ENTRY* le;
3352 
3353  le = fcb->extents.Blink;
3354  while (le != &fcb->extents) {
3356 
3357  if (!ext2->ignore) {
3358  ext = ext2;
3359  break;
3360  }
3361 
3362  le = le->Blink;
3363  }
3364 
3365  oldalloc = 0;
3366  if (ext) {
3367  EXTENT_DATA* ed = &ext->extent_data;
3368  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ed->data;
3369 
3370  oldalloc = ext->offset + (ed->type == EXTENT_TYPE_INLINE ? ed->decoded_size : ed2->num_bytes);
3371  cur_inline = ed->type == EXTENT_TYPE_INLINE;
3372 
3373  if (cur_inline && end > fcb->Vcb->options.max_inline) {
3374  uint64_t origlength, length;
3375  uint8_t* data;
3376 
3377  TRACE("giving inline file proper extents\n");
3378 
3379  origlength = ed->decoded_size;
3380 
3381  cur_inline = false;
3382 
3383  length = sector_align(origlength, fcb->Vcb->superblock.sector_size);
3384 
3386  if (!data) {
3387  ERR("could not allocate %I64x bytes for data\n", length);
3389  }
3390 
3391  Status = read_file(fcb, data, 0, origlength, NULL, Irp);
3392  if (!NT_SUCCESS(Status)) {
3393  ERR("read_file returned %08lx\n", Status);
3394  ExFreePool(data);
3395  return Status;
3396  }
3397 
3398  RtlZeroMemory(data + origlength, (ULONG)(length - origlength));
3399 
3401  if (!NT_SUCCESS(Status)) {
3402  ERR("excise_extents returned %08lx\n", Status);
3403  ExFreePool(data);
3404  return Status;
3405  }
3406 
3407  Status = do_write_file(fcb, 0, length, data, Irp, false, 0, rollback);
3408  if (!NT_SUCCESS(Status)) {
3409  ERR("do_write_file returned %08lx\n", Status);
3410  ExFreePool(data);
3411  return Status;
3412  }
3413 
3414  oldalloc = ext->offset + length;
3415 
3416  ExFreePool(data);
3417  }
3418 
3419  if (cur_inline) {
3420  uint16_t edsize;
3421 
3422  if (end > oldalloc) {
3423  edsize = (uint16_t)(offsetof(EXTENT_DATA, data[0]) + end - ext->offset);
3424  ed = ExAllocatePoolWithTag(PagedPool, edsize, ALLOC_TAG);
3425 
3426  if (!ed) {
3427  ERR("out of memory\n");
3429  }
3430 
3431  ed->generation = fcb->Vcb->superblock.generation;
3432  ed->decoded_size = end - ext->offset;
3436  ed->type = EXTENT_TYPE_INLINE;
3437 
3438  Status = read_file(fcb, ed->data, ext->offset, oldalloc, NULL, Irp);
3439  if (!NT_SUCCESS(Status)) {
3440  ERR("read_file returned %08lx\n", Status);
3441  ExFreePool(ed);
3442  return Status;
3443  }
3444 
3445  RtlZeroMemory(ed->data + oldalloc - ext->offset, (ULONG)(end - oldalloc));
3446 
3447  remove_fcb_extent(fcb, ext, rollback);
3448 
3449  Status = add_extent_to_fcb(fcb, ext->offset, ed, edsize, ext->unique, NULL, rollback);
3450  if (!NT_SUCCESS(Status)) {
3451  ERR("add_extent_to_fcb returned %08lx\n", Status);
3452  ExFreePool(ed);
3453  return Status;
3454  }
3455 
3456  ExFreePool(ed);
3457 
3458  fcb->extents_changed = true;
3460  }
3461 
3462  TRACE("extending inline file (oldalloc = %I64x, end = %I64x)\n", oldalloc, end);
3463 
3465  TRACE("setting st_size to %I64x\n", end);
3466 
3468 
3469  fcb->Header.AllocationSize.QuadPart = fcb->Header.FileSize.QuadPart = fcb->Header.ValidDataLength.QuadPart = end;
3470  } else {
3471  newalloc = sector_align(end, fcb->Vcb->superblock.sector_size);
3472 
3473  if (newalloc > oldalloc) {
3474  if (prealloc) {
3475  // FIXME - try and extend previous extent first
3476 
3477  Status = insert_prealloc_extent(fcb, oldalloc, newalloc - oldalloc, rollback);
3478 
3479  if (!NT_SUCCESS(Status) && Status != STATUS_DISK_FULL) {
3480  ERR("insert_prealloc_extent returned %08lx\n", Status);
3481  return Status;
3482  }
3483  }
3484 
3485  fcb->extents_changed = true;
3486  }
3487 
3489  fcb->inode_item_changed = true;
3491 
3492  TRACE("setting st_size to %I64x\n", end);
3493 
3494  TRACE("newalloc = %I64x\n", newalloc);
3495 
3496  fcb->Header.AllocationSize.QuadPart = newalloc;
3497  fcb->Header.FileSize.QuadPart = fcb->Header.ValidDataLength.QuadPart = end;
3498  }
3499  } else {
3500  if (end > fcb->Vcb->options.max_inline) {
3501  newalloc = sector_align(end, fcb->Vcb->superblock.sector_size);
3502 
3503  if (prealloc) {
3504  Status = insert_prealloc_extent(fcb, 0, newalloc, rollback);
3505 
3506  if (!NT_SUCCESS(Status) && Status != STATUS_DISK_FULL) {
3507  ERR("insert_prealloc_extent returned %08lx\n", Status);
3508  return Status;
3509  }
3510  }
3511 
3512  fcb->extents_changed = true;
3513  fcb->inode_item_changed = true;
3515 
3517  TRACE("setting st_size to %I64x\n", end);
3518 
3519  TRACE("newalloc = %I64x\n", newalloc);
3520 
3521  fcb->Header.AllocationSize.QuadPart = newalloc;
3522  fcb->Header.FileSize.QuadPart = fcb->Header.ValidDataLength.QuadPart = end;
3523  } else {
3524  EXTENT_DATA* ed;
3525  uint16_t edsize;
3526 
3527  edsize = (uint16_t)(offsetof(EXTENT_DATA, data[0]) + end);
3528  ed = ExAllocatePoolWithTag(PagedPool, edsize, ALLOC_TAG);
3529 
3530  if (!ed) {
3531  ERR("out of memory\n");
3533  }
3534 
3535  ed->generation = fcb->Vcb->superblock.generation;
3536  ed->decoded_size = end;
3540  ed->type = EXTENT_TYPE_INLINE;
3541 
3542  RtlZeroMemory(ed->data, (ULONG)end);
3543 
3544  Status = add_extent_to_fcb(fcb, 0, ed, edsize, false, NULL, rollback);
3545  if (!NT_SUCCESS(Status)) {
3546  ERR("add_extent_to_fcb returned %08lx\n", Status);
3547  ExFreePool(ed);
3548  return Status;
3549  }
3550 
3551  ExFreePool(ed);
3552 
3553  fcb->extents_changed = true;
3554  fcb->inode_item_changed = true;
3556 
3558  TRACE("setting st_size to %I64x\n", end);
3559 
3561 
3562  fcb->Header.AllocationSize.QuadPart = fcb->Header.FileSize.QuadPart = fcb->Header.ValidDataLength.QuadPart = end;
3563  }
3564  }
3565  }
3566 
3567  return STATUS_SUCCESS;
3568 }
uint64_t generation
Definition: btrfs.h:358
NTSTATUS do_write_file(fcb *fcb, uint64_t start_data, uint64_t end_data, void *data, PIRP Irp, bool file_write, uint32_t irp_offset, LIST_ENTRY *rollback) __attribute__((nonnull(1
uint8_t type
Definition: btrfs.h:363
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
uint64_t decoded_size
Definition: btrfs.h:359
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
uint8_t encryption
Definition: btrfs.h:361
#define ALLOC_TAG
Definition: btrfs_drv.h:87
#define EXTENT_TYPE_INLINE
Definition: btrfs.h:74
_In_ PIRP Irp
Definition: csq.h:116
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
bool extents_changed
Definition: btrfs_drv.h:323
#define BTRFS_ENCODING_NONE
Definition: btrfs.h:72
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
uint16_t encoding
Definition: btrfs.h:362
#define BTRFS_ENCRYPTION_NONE
Definition: btrfs.h:70
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LIST_ENTRY extents
Definition: btrfs_drv.h:300
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const BYTE ext2[]
Definition: encode.c:2699
NTSTATUS bool void NTSTATUS add_extent_to_fcb(_In_ fcb *fcb, _In_ uint64_t offset, _In_reads_bytes_(edsize) EXTENT_DATA *ed, _In_ uint16_t edsize, _In_ bool unique, _In_opt_ _When_(return >=0, __drv_aliasesMem) void *csum, _In_ LIST_ENTRY *rollback) __attribute__((nonnull(1
Definition: typedefs.h:119
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t num_bytes
Definition: btrfs.h:371
uint64_t st_blocks
Definition: btrfs.h:290
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t data[1]
Definition: btrfs.h:364
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
UINT64 uint64_t
Definition: types.h:77
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool prealloc
Definition: btrfs_drv.h:1355
Definition: list.h:27
#define NULL
Definition: types.h:112
NTSTATUS stream_set_end_of_file_information(device_extension *Vcb, uint16_t end, fcb *fcb, file_ref *fileref, bool advance_only)
Definition: fileinfo.c:3170
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
bool ads
Definition: btrfs_drv.h:330
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
bool inode_item_changed
Definition: btrfs_drv.h:306
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
uint8_t compression
Definition: btrfs.h:360

◆ __attribute__() [17/18]

__attribute__ ( (nonnull(1, 2, 5, 6, 11))  )

Definition at line 3570 of file write.c.

3572  {
3573  EXTENT_DATA* ed = &ext->extent_data;
3574  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ed->data;
3575  NTSTATUS Status;
3576  chunk* c = NULL;
3577 
3578  if (start_data <= ext->offset && end_data >= ext->offset + ed2->num_bytes) { // replace all
3579  extent* newext;
3580 
3581  newext = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3582  if (!newext) {
3583  ERR("out of memory\n");
3585  }
3586 
3587  RtlCopyMemory(&newext->extent_data, &ext->extent_data, ext->datalen);
3588 
3590 
3591  Status = write_data_complete(fcb->Vcb, ed2->address + ed2->offset, (uint8_t*)data + ext->offset - start_data, (uint32_t)ed2->num_bytes, Irp,
3592  NULL, file_write, irp_offset + ext->offset - start_data, priority);
3593  if (!NT_SUCCESS(Status)) {
3594  ERR("write_data_complete returned %08lx\n", Status);
3595  return Status;
3596  }
3597 
3599  ULONG sl = (ULONG)(ed2->num_bytes >> fcb->Vcb->sector_shift);
3600  void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG);
3601 
3602  if (!csum) {
3603  ERR("out of memory\n");
3604  ExFreePool(newext);
3606  }
3607 
3608  do_calc_job(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum);
3609 
3610  newext->csum = csum;
3611  } else
3612  newext->csum = NULL;
3613 
3614  *written = ed2->num_bytes;
3615 
3616  newext->offset = ext->offset;
3617  newext->datalen = ext->datalen;
3618  newext->unique = ext->unique;
3619  newext->ignore = false;
3620  newext->inserted = true;
3621  InsertHeadList(&ext->list_entry, &newext->list_entry);
3622 
3623  add_insert_extent_rollback(rollback, fcb, newext);
3624 
3625  remove_fcb_extent(fcb, ext, rollback);
3626 
3628  } else if (start_data <= ext->offset && end_data < ext->offset + ed2->num_bytes) { // replace beginning
3629  EXTENT_DATA2* ned2;
3630  extent *newext1, *newext2;
3631 
3632  newext1 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3633  if (!newext1) {
3634  ERR("out of memory\n");
3636  }
3637 
3638  newext2 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3639  if (!newext2) {
3640  ERR("out of memory\n");
3641  ExFreePool(newext1);
3643  }
3644 
3645  RtlCopyMemory(&newext1->extent_data, &ext->extent_data, ext->datalen);
3647  ned2 = (EXTENT_DATA2*)newext1->extent_data.data;
3648  ned2->num_bytes = end_data - ext->offset;
3649 
3650  RtlCopyMemory(&newext2->extent_data, &ext->extent_data, ext->datalen);
3651  ned2 = (EXTENT_DATA2*)newext2->extent_data.data;
3652  ned2->offset += end_data - ext->offset;
3653  ned2->num_bytes -= end_data - ext->offset;
3654 
3655  Status = write_data_complete(fcb->Vcb, ed2->address + ed2->offset, (uint8_t*)data + ext->offset - start_data, (uint32_t)(end_data - ext->offset),
3656  Irp, NULL, file_write, irp_offset + ext->offset - start_data, priority);
3657  if (!NT_SUCCESS(Status)) {
3658  ERR("write_data_complete returned %08lx\n", Status);
3659  ExFreePool(newext1);
3660  ExFreePool(newext2);
3661  return Status;
3662  }
3663 
3665  ULONG sl = (ULONG)((end_data - ext->offset) >> fcb->Vcb->sector_shift);
3666  void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG);
3667 
3668  if (!csum) {
3669  ERR("out of memory\n");
3670  ExFreePool(newext1);
3671  ExFreePool(newext2);
3673  }
3674 
3675  do_calc_job(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum);
3676 
3677  newext1->csum = csum;
3678  } else
3679  newext1->csum = NULL;
3680 
3681  *written = end_data - ext->offset;
3682 
3683  newext1->offset = ext->offset;
3684  newext1->datalen = ext->datalen;
3685  newext1->unique = ext->unique;
3686  newext1->ignore = false;
3687  newext1->inserted = true;
3688  InsertHeadList(&ext->list_entry, &newext1->list_entry);
3689 
3690  add_insert_extent_rollback(rollback, fcb, newext1);
3691 
3692  newext2->offset = end_data;
3693  newext2->datalen = ext->datalen;
3694  newext2->unique = ext->unique;
3695  newext2->ignore = false;
3696  newext2->inserted = true;
3697  newext2->csum = NULL;
3698  add_extent(fcb, &newext1->list_entry, newext2);
3699 
3700  add_insert_extent_rollback(rollback, fcb, newext2);
3701 
3703 
3704  if (!c)
3705  ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
3706  else {
3707  Status = update_changed_extent_ref(fcb->Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, 1,
3709 
3710  if (!NT_SUCCESS(Status)) {
3711  ERR("update_changed_extent_ref returned %08lx\n", Status);
3712  return Status;
3713  }
3714  }
3715 
3716  remove_fcb_extent(fcb, ext, rollback);
3717  } else if (start_data > ext->offset && end_data >= ext->offset + ed2->num_bytes) { // replace end
3718  EXTENT_DATA2* ned2;
3719  extent *newext1, *newext2;
3720 
3721  newext1 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3722  if (!newext1) {
3723  ERR("out of memory\n");
3725  }
3726 
3727  newext2 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3728  if (!newext2) {
3729  ERR("out of memory\n");
3730  ExFreePool(newext1);
3732  }
3733 
3734  RtlCopyMemory(&newext1->extent_data, &ext->extent_data, ext->datalen);
3735 
3736  ned2 = (EXTENT_DATA2*)newext1->extent_data.data;
3737  ned2->num_bytes = start_data - ext->offset;
3738 
3739  RtlCopyMemory(&newext2->extent_data, &ext->extent_data, ext->datalen);
3740 
3742  ned2 = (EXTENT_DATA2*)newext2->extent_data.data;
3743  ned2->offset += start_data - ext->offset;
3744  ned2->num_bytes = ext->offset + ed2->num_bytes - start_data;
3745 
3746  Status = write_data_complete(fcb->Vcb, ed2->address + ned2->offset, data, (uint32_t)ned2->num_bytes, Irp, NULL, file_write, irp_offset, priority);
3747  if (!NT_SUCCESS(Status)) {
3748  ERR("write_data_complete returned %08lx\n", Status);
3749  ExFreePool(newext1);
3750  ExFreePool(newext2);
3751  return Status;
3752  }
3753 
3755  ULONG sl = (ULONG)(ned2->num_bytes >> fcb->Vcb->sector_shift);
3756  void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG);
3757 
3758  if (!csum) {
3759  ERR("out of memory\n");
3760  ExFreePool(newext1);
3761  ExFreePool(newext2);
3763  }
3764 
3765  do_calc_job(fcb->Vcb, data, sl, csum);
3766 
3767  newext2->csum = csum;
3768  } else
3769  newext2->csum = NULL;
3770 
3771  *written = ned2->num_bytes;
3772 
3773  newext1->offset = ext->offset;
3774  newext1->datalen = ext->datalen;
3775  newext1->unique = ext->unique;
3776  newext1->ignore = false;
3777  newext1->inserted = true;
3778  newext1->csum = NULL;
3779  InsertHeadList(&ext->list_entry, &newext1->list_entry);
3780 
3781  add_insert_extent_rollback(rollback, fcb, newext1);
3782 
3783  newext2->offset = start_data;
3784  newext2->datalen = ext->datalen;
3785  newext2->unique = ext->unique;
3786  newext2->ignore = false;
3787  newext2->inserted = true;
3788  add_extent(fcb, &newext1->list_entry, newext2);
3789 
3790  add_insert_extent_rollback(rollback, fcb, newext2);
3791 
3793 
3794  if (!c)
3795  ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
3796  else {
3797  Status = update_changed_extent_ref(fcb->Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, 1,
3799 
3800  if (!NT_SUCCESS(Status)) {
3801  ERR("update_changed_extent_ref returned %08lx\n", Status);
3802  return Status;
3803  }
3804  }
3805 
3806  remove_fcb_extent(fcb, ext, rollback);
3807  } else if (start_data > ext->offset && end_data < ext->offset + ed2->num_bytes) { // replace middle
3808  EXTENT_DATA2* ned2;
3809  extent *newext1, *newext2, *newext3;
3810 
3811  newext1 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3812  if (!newext1) {
3813  ERR("out of memory\n");
3815  }
3816 
3817  newext2 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3818  if (!newext2) {
3819  ERR("out of memory\n");
3820  ExFreePool(newext1);
3822  }
3823 
3824  newext3 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
3825  if (!newext3) {
3826  ERR("out of memory\n");
3827  ExFreePool(newext1);
3828  ExFreePool(newext2);
3830  }
3831 
3832  RtlCopyMemory(&newext1->extent_data, &ext->extent_data, ext->datalen);
3833  RtlCopyMemory(&newext2->extent_data, &ext->extent_data, ext->datalen);
3834  RtlCopyMemory(&newext3->extent_data, &ext->extent_data, ext->datalen);
3835 
3836  ned2 = (EXTENT_DATA2*)newext1->extent_data.data;
3837  ned2->num_bytes = start_data - ext->offset;
3838 
3840  ned2 = (EXTENT_DATA2*)newext2->extent_data.data;
3841  ned2->offset += start_data - ext->offset;
3842  ned2->num_bytes = end_data - start_data;
3843 
3844  ned2 = (EXTENT_DATA2*)newext3->extent_data.data;
3845  ned2->offset += end_data - ext->offset;
3846  ned2->num_bytes -= end_data - ext->offset;
3847 
3848  ned2 = (EXTENT_DATA2*)newext2->extent_data.data;
3849  Status = write_data_complete(fcb->Vcb, ed2->address + ned2->offset, data, (uint32_t)(end_data - start_data), Irp, NULL, file_write, irp_offset, priority);
3850  if (!NT_SUCCESS(Status)) {
3851  ERR("write_data_complete returned %08lx\n", Status);
3852  ExFreePool(newext1);
3853  ExFreePool(newext2);
3854  ExFreePool(newext3);
3855  return Status;
3856  }
3857 
3859  ULONG sl = (ULONG)((end_data - start_data) >> fcb->Vcb->sector_shift);
3860  void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG);
3861 
3862  if (!csum) {
3863  ERR("out of memory\n");
3864  ExFreePool(newext1);
3865  ExFreePool(newext2);
3866  ExFreePool(newext3);
3868  }
3869 
3870  do_calc_job(fcb->Vcb, data, sl, csum);
3871 
3872  newext2->csum = csum;
3873  } else
3874  newext2->csum = NULL;
3875 
3876  *written = end_data - start_data;
3877 
3878  newext1->offset = ext->offset;
3879  newext1->datalen = ext->datalen;
3880  newext1->unique = ext->unique;
3881  newext1->ignore = false;
3882  newext1->inserted = true;
3883  newext1->csum = NULL;
3884  InsertHeadList(&ext->list_entry, &newext1->list_entry);
3885 
3886  add_insert_extent_rollback(rollback, fcb, newext1);
3887 
3888  newext2->offset = start_data;
3889  newext2->datalen = ext->datalen;
3890  newext2->unique = ext->unique;
3891  newext2->ignore = false;
3892  newext2->inserted = true;
3893  add_extent(fcb, &newext1->list_entry, newext2);
3894 
3895  add_insert_extent_rollback(rollback, fcb, newext2);
3896 
3897  newext3->offset = end_data;
3898  newext3->datalen = ext->datalen;
3899  newext3->unique = ext->unique;
3900  newext3->ignore = false;
3901  newext3->inserted = true;
3902  newext3->csum = NULL;
3903  add_extent(fcb, &newext2->list_entry, newext3);
3904 
3905  add_insert_extent_rollback(rollback, fcb, newext3);
3906 
3908 
3909  if (!c)
3910  ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
3911  else {
3912  Status = update_changed_extent_ref(fcb->Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, 2,
3914 
3915  if (!NT_SUCCESS(Status)) {
3916  ERR("update_changed_extent_ref returned %08lx\n", Status);
3917  return Status;
3918  }
3919  }
3920 
3921  remove_fcb_extent(fcb, ext, rollback);
3922  }
3923 
3924  if (c)
3925  c->changed = true;
3926 
3927  return STATUS_SUCCESS;
3928 }
uint8_t type
Definition: btrfs.h:363
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS update_changed_extent_ref(device_extension *Vcb, chunk *c, uint64_t address, uint64_t size, uint64_t root, uint64_t objid, uint64_t offset, int32_t count, bool no_csum, bool superseded, PIRP Irp)
Definition: extent-tree.c:1951
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
void * csum
Definition: btrfs_drv.h:233
LIST_ENTRY list_entry
Definition: btrfs_drv.h:235
uint16_t datalen
Definition: btrfs_drv.h:229
uint32_t flags
Definition: btrfs.h:297
if(dx==0 &&dy==0)
Definition: linetemp.h:174
bool ignore
Definition: btrfs_drv.h:231
_In_ fcb _In_ chunk _In_ uint64_t start_data
Definition: btrfs_drv.h:1355
#define ALLOC_TAG
Definition: btrfs_drv.h:87
bool inserted
Definition: btrfs_drv.h:232
void do_calc_job(device_extension *Vcb, uint8_t *data, uint32_t sectors, void *csum)
Definition: calcthread.c:141
_In_ PIRP Irp
Definition: csq.h:116
uint64_t address
Definition: btrfs.h:368
uint64_t offset
Definition: btrfs_drv.h:228
WDF_INTERRUPT_PRIORITY priority
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
uint64_t size
Definition: btrfs.h:369
bool unique
Definition: btrfs_drv.h:230
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:289
GLintptr offset
Definition: glext.h:5920
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
const GLubyte * c
Definition: glext.h:8905
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t num_bytes
Definition: btrfs.h:371
NTSTATUS NTSTATUS NTSTATUS write_data_complete(device_extension *Vcb, uint64_t address, void *data, uint32_t length, PIRP Irp, chunk *c, bool file_write, uint64_t irp_offset, ULONG priority) __attribute__((nonnull(1
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:75
#define ERR(fmt,...)
Definition: debug.h:110
uint8_t data[1]
Definition: btrfs.h:364
struct _root * subvol
Definition: btrfs_drv.h:288
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
UINT32 uint32_t
Definition: types.h:75
LOCAL int file_write(FILE *outfile)
Definition: write.c:1913
Definition: ffs.h:52
EXTENT_DATA extent_data
Definition: btrfs_drv.h:237
NTSTATUS bool void NTSTATUS void add_extent(_In_ fcb *fcb, _In_ LIST_ENTRY *prevextle, _In_ __drv_aliasesMem extent *newext) __attribute__((nonnull(1
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint64_t offset
Definition: btrfs.h:370
#define STATUS_SUCCESS
Definition: shellext.h:65
#define uint32_t
Definition: nsiface.idl:61
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS chunk * get_chunk_from_address(device_extension *Vcb, uint64_t address) __attribute__((nonnull(1)))

◆ __attribute__() [18/18]

__attribute__ ( (nonnull(1, 2, 4, 5, 11))  )

Definition at line 4098 of file write.c.

4100  {
4103  EXTENT_DATA* ed2;
4104  uint64_t off64, newlength, start_data, end_data;
4105  uint32_t bufhead;
4106  bool make_inline;
4107  INODE_ITEM* origii;
4108  bool changed_length = false;
4109  NTSTATUS Status;
4111  BTRFS_TIME now;
4112  fcb* fcb;
4113  ccb* ccb;
4114  file_ref* fileref;
4115  bool paging_lock = false, acquired_fcb_lock = false, acquired_tree_lock = false, pagefile;
4116  ULONG filter = 0;
4117 
4118  TRACE("(%p, %p, %I64x, %p, %lx, %u, %u)\n", Vcb, FileObject, offset.QuadPart, buf, *length, paging_io, no_cache);
4119 
4120  if (*length == 0) {
4121  TRACE("returning success for zero-length write\n");
4122  return STATUS_SUCCESS;
4123  }
4124 
4125  if (!FileObject) {
4126  ERR("error - FileObject was NULL\n");
4127  return STATUS_ACCESS_DENIED;
4128  }
4129 
4130  fcb = FileObject->FsContext;
4131  ccb = FileObject->FsContext2;
4132  fileref = ccb ? ccb->fileref : NULL;
4133 
4134  if (!fcb->ads && fcb->type != BTRFS_TYPE_FILE && fcb->type != BTRFS_TYPE_SYMLINK) {
4135  WARN("tried to write to something other than a file or symlink (inode %I64x, type %u, %p, %p)\n", fcb->inode, fcb->type, &fcb->type, fcb);
4137  }
4138 
4139  if (offset.LowPart == FILE_WRITE_TO_END_OF_FILE && offset.HighPart == -1)
4140  offset = fcb->Header.FileSize;
4141 
4142  off64 = offset.QuadPart;
4143 
4144  TRACE("fcb->Header.Flags = %x\n", fcb->Header.Flags);
4145 
4146  if (!no_cache && !CcCanIWrite(FileObject, *length, wait, deferred_write))
4147  return STATUS_PENDING;
4148 
4149  if (!wait && no_cache)
4150  return STATUS_PENDING;
4151 
4152  if (no_cache && !paging_io && FileObject->SectionObjectPointer->DataSectionObject) {
4154 
4155  ExAcquireResourceExclusiveLite(fcb->Header.PagingIoResource, true);
4156 
4157  CcFlushCache(FileObject->SectionObjectPointer, &offset, *length, &iosb);
4158 
4159  if (!NT_SUCCESS(iosb.Status)) {
4160  ExReleaseResourceLite(fcb->Header.PagingIoResource);
4161  ERR("CcFlushCache returned %08lx\n", iosb.Status);
4162  return iosb.Status;
4163  }
4164 
4165  paging_lock = true;
4166 
4167  CcPurgeCacheSection(FileObject->SectionObjectPointer, &offset, *length, false);
4168  }
4169 
4170  if (paging_io) {
4171  if (!ExAcquireResourceSharedLite(fcb->Header.PagingIoResource, wait)) {