*参照元 [#pc715bee] #backlinks *説明 [#j9cfcbb0] -パス: [[linux-2.6.33/mm/mmap.c]] -FIXME: これは何? --説明 **引数 [#m7057ac7] -struct file *file -- --[[linux-2.6.33/file]] -unsigned long addr -- -unsigned long len -- -unsigned long prot -- -unsigned long flags -- -unsigned long pgoff -- **返り値 [#mb6e3e83] -unsigned long -- **参考 [#d593394c] *実装 [#ye9c9916] /* * The caller must hold down_write(¤t->mm->mmap_sem). */ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { struct mm_struct * mm = current->mm; struct inode *inode; unsigned int vm_flags; int error; unsigned long reqprot = prot; - --[[linux-2.6.33/current(global)]] --[[linux-2.6.33/mm_struct]] --[[linux-2.6.33/inode]] /* * Does the application expect PROT_READ to imply PROT_EXEC? * * (the exception is when the underlying filesystem is noexec * mounted, in which case we dont add PROT_EXEC.) */ if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC))) prot |= PROT_EXEC; - --[[linux-2.6.33/PROT_READ]] --[[linux-2.6.33/READ_IMPLIES_EXEC]] --[[linux-2.6.33/MNT_NOEXEC]] --[[linux-2.6.33/PROT_EXEC]] if (!len) return -EINVAL; - --[[linux-2.6.33/EINVAL]] if (!(flags & MAP_FIXED)) addr = round_hint_to_min(addr); - --[[linux-2.6.33/MAP_FIXED]] --[[linux-2.6.33/round_hint_to_min()]] /* Careful about overflows.. */ len = PAGE_ALIGN(len); if (!len) return -ENOMEM; - --[[linux-2.6.33/PAGE_ALIGN()]] --[[linux-2.6.33/ENOMEM]] /* offset overflow? */ if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) return -EOVERFLOW; - --[[linux-2.6.33/PAGE_SHIFT]] --[[linux-2.6.33/EOVERFLOW]] /* Too many mappings? */ if (mm->map_count > sysctl_max_map_count) return -ENOMEM; - --[[linux-2.6.33/sysctl_max_map_count(global)]] /* Obtain the address to map to. we verify (or select) it and ensure * that it represents a valid section of the address space. */ addr = get_unmapped_area(file, addr, len, pgoff, flags); if (addr & ~PAGE_MASK) return addr; - --[[linux-2.6.33/get_unmapped_area()]] --[[linux-2.6.33/PAGE_MASK]] /* Do simple checking here so the lower-level routines won't have * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; - --[[linux-2.6.33/calc_vm_prot_bits()]] --[[linux-2.6.33/calc_vm_flag_bits()]] --[[linux-2.6.33/VM_MAYREAD]] --[[linux-2.6.33/VM_MAYWRITE]] --[[linux-2.6.33/VM_MAYEXEC]] if (flags & MAP_LOCKED) if (!can_do_mlock()) return -EPERM; - --[[linux-2.6.33/MAP_LOCKED]] --[[linux-2.6.33/can_do_mlock()]] --[[linux-2.6.33/EPERM]] /* mlock MCL_FUTURE? */ if (vm_flags & VM_LOCKED) { unsigned long locked, lock_limit; locked = len >> PAGE_SHIFT; locked += mm->locked_vm; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; lock_limit >>= PAGE_SHIFT; if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } - --[[linux-2.6.33/VM_LOCKED]] --[[linux-2.6.33/RLIMIT_MEMLOCK]] --[[linux-2.6.33/capable()]] --[[linux-2.6.33/CAP_IPC_LOCK]] --[[linux-2.6.33/EAGAIN]] inode = file ? file->f_path.dentry->d_inode : NULL; if (file) { switch (flags & MAP_TYPE) { case MAP_SHARED: if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) return -EACCES; - --[[linux-2.6.33/MAP_TYPE]] --[[linux-2.6.33/PROT_WRITE]] --[[linux-2.6.33/FMODE_WRITE]] --[[linux-2.6.33/EACCES]] /* * Make sure we don't allow writing to an append-only * file.. */ if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE)) return -EACCES; - --[[linux-2.6.33/IS_APPEND()]] /* * Make sure there are no mandatory locks on the file. */ if (locks_verify_locked(inode)) return -EAGAIN; - --[[linux-2.6.33/locks_verify_locked()]] vm_flags |= VM_SHARED | VM_MAYSHARE; if (!(file->f_mode & FMODE_WRITE)) vm_flags &= ~(VM_MAYWRITE | VM_SHARED); /* fall through */ - --[[linux-2.6.33/VM_MAYSHARE]] case MAP_PRIVATE: if (!(file->f_mode & FMODE_READ)) return -EACCES; - --[[linux-2.6.33/MAP_PRIVATE]] --[[linux-2.6.33/FMODE_READ]] if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) { if (vm_flags & VM_EXEC) return -EPERM; vm_flags &= ~VM_MAYEXEC; } - --[[linux-2.6.33/MNT_NOEXEC]] --[[linux-2.6.33/VM_EXEC]] --[[linux-2.6.33/VM_MAYEXEC]] if (!file->f_op || !file->f_op->mmap) return -ENODEV; break; - --[[linux-2.6.33/ENODEV]] default: return -EINVAL; - --[[linux-2.6.33/EINVAL]] } } else { switch (flags & MAP_TYPE) { case MAP_SHARED: /* * Ignore pgoff. */ pgoff = 0; vm_flags |= VM_SHARED | VM_MAYSHARE; break; case MAP_PRIVATE: /* * Set pgoff according to addr for anon_vma. */ pgoff = addr >> PAGE_SHIFT; break; default: return -EINVAL; } } error = security_file_mmap(file, reqprot, prot, flags, addr, 0); if (error) return error; - --[[linux-2.6.33/security_file_mmap()]] return mmap_region(file, addr, len, flags, vm_flags, pgoff); - --[[linux-2.6.33/mmap_region()]] } EXPORT_SYMBOL(do_mmap_pgoff); -ライセンスに関係なくシンボルを公開する。 --[[linux-2.6.33/EXPORT_SYMBOL()]] *コメント [#s12f1c2a]