*参照元 [#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(&current->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]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS