static struct cfs_trace_page *cfs_tage_alloc(int gfp) { cfs_page_t *page; struct cfs_trace_page *tage; /* My caller is trying to free memory */ if (!cfs_in_interrupt() && cfs_memory_pressure_get()) return NULL; /* * Don't spam console with allocation failures: they will be reported * by upper layer anyway. */ gfp |= CFS_ALLOC_NOWARN; page = cfs_alloc_page(gfp); if (page == NULL) return NULL; tage = cfs_alloc(sizeof(*tage), gfp); if (tage == NULL) { cfs_free_page(page); return NULL; } tage->page = page; cfs_atomic_inc(&cfs_tage_allocated); return tage; }
struct file *filp_open(const char *name, int flags, int mode, int *err) { struct file *fp = NULL; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; IO_STATUS_BLOCK IoStatus; ACCESS_MASK DesiredAccess; ULONG CreateDisposition; ULONG ShareAccess; ULONG CreateOptions; USHORT NameLength = 0; USHORT PrefixLength = 0; UNICODE_STRING UnicodeName; PWCHAR UnicodeString = NULL; ANSI_STRING AnsiName; PUCHAR AnsiString = NULL; /* Analyze the flags settings */ if (cfs_is_flag_set(flags, O_WRONLY)) { DesiredAccess = (GENERIC_WRITE | SYNCHRONIZE); ShareAccess = 0; } else if (cfs_is_flag_set(flags, O_RDWR)) { DesiredAccess = (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE); ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; } else { DesiredAccess = (GENERIC_READ | SYNCHRONIZE); ShareAccess = FILE_SHARE_READ; } if (cfs_is_flag_set(flags, O_CREAT)) { if (cfs_is_flag_set(flags, O_EXCL)) { CreateDisposition = FILE_CREATE; } else { CreateDisposition = FILE_OPEN_IF; } } else { CreateDisposition = FILE_OPEN; } if (cfs_is_flag_set(flags, O_TRUNC)) { if (cfs_is_flag_set(flags, O_EXCL)) { CreateDisposition = FILE_OVERWRITE; } else { CreateDisposition = FILE_OVERWRITE_IF; } } CreateOptions = 0; if (cfs_is_flag_set(flags, O_DIRECTORY)) { cfs_set_flag(CreateOptions, FILE_DIRECTORY_FILE); } if (cfs_is_flag_set(flags, O_SYNC)) { cfs_set_flag(CreateOptions, FILE_WRITE_THROUGH); } if (cfs_is_flag_set(flags, O_DIRECT)) { cfs_set_flag(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING); } /* Initialize the unicode path name for the specified file */ NameLength = (USHORT)strlen(name); /* Check file & path name */ if (name[0] != '\\') { if (NameLength < 1 || name[1] != ':' || !is_drv_letter_valid(name[0])) { /* invalid file path name */ return ERR_PTR(-EINVAL); } PrefixLength = (USHORT)strlen(dos_file_prefix[0]); } else { int i, j; for (i = 0; i < 3 && dos_file_prefix[i] != NULL; i++) { j = strlen(dos_file_prefix[i]); if (NameLength > j && _strnicmp(dos_file_prefix[i], name, j) == 0) break; } if (i >= 3) return ERR_PTR(-EINVAL); } AnsiString = cfs_alloc(sizeof(CHAR) * (NameLength + PrefixLength + 1), CFS_ALLOC_ZERO); if (NULL == AnsiString) return ERR_PTR(-ENOMEM); UnicodeString = cfs_alloc(sizeof(WCHAR) * (NameLength + PrefixLength + 1), CFS_ALLOC_ZERO); if (NULL == UnicodeString) { cfs_free(AnsiString); return ERR_PTR(-ENOMEM); } if (PrefixLength) { RtlCopyMemory(&AnsiString[0], dos_file_prefix[0], PrefixLength); } RtlCopyMemory(&AnsiString[PrefixLength], name, NameLength); NameLength += PrefixLength; AnsiName.MaximumLength = NameLength + 1; AnsiName.Length = NameLength; AnsiName.Buffer = AnsiString; UnicodeName.MaximumLength = (NameLength + 1) * sizeof(WCHAR); UnicodeName.Length = 0; UnicodeName.Buffer = (PWSTR)UnicodeString; RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE); /* Setup the object attributes structure for the file. */ InitializeObjectAttributes( &ObjectAttributes, &UnicodeName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); /* Now to open or create the file now */ Status = ZwCreateFile( &FileHandle, DesiredAccess, &ObjectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, ShareAccess, CreateDisposition, CreateOptions, NULL, 0 ); /* Check the returned status of IoStatus... */ if (!NT_SUCCESS(IoStatus.Status)) { cfs_free(UnicodeString); cfs_free(AnsiString); return ERR_PTR(cfs_error_code(IoStatus.Status)); } /* Allocate the file_t: libcfs file object */ fp = cfs_alloc(sizeof(*fp) + NameLength, CFS_ALLOC_ZERO); if (NULL == fp) { Status = ZwClose(FileHandle); ASSERT(NT_SUCCESS(Status)); cfs_free(UnicodeString); cfs_free(AnsiString); return ERR_PTR(-ENOMEM); } fp->f_handle = FileHandle; strcpy(fp->f_name, name); fp->f_flags = flags; fp->f_mode = (mode_t)mode; fp->f_count = 1; /* free the memory of temporary name strings */ cfs_free(UnicodeString); cfs_free(AnsiString); return fp; }