⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locking

📁 linux 内核源代码
💻
📖 第 1 页 / 共 2 页
字号:
under spinlock (it cannot block) and is sometimes called with the pagenot locked.	->bmap() is currently used by legacy ioctl() (FIBMAP) provided by somefilesystems and by the swapper. The latter will eventually go away. Allinstances do not actually need the BKL. Please, keep it that way and don'tbreed new callers.	->invalidatepage() is called when the filesystem must attempt to dropsome or all of the buffers from the page when it is being truncated.  Itreturns zero on success.  If ->invalidatepage is zero, the kernel usesblock_invalidatepage() instead.	->releasepage() is called when the kernel is about to try to drop thebuffers from the page in preparation for freeing it.  It returns zero toindicate that the buffers are (or may be) freeable.  If ->releasepage is zero,the kernel assumes that the fs has no private interest in the buffers.	->launder_page() may be called prior to releasing a page ifit is still found to be dirty. It returns zero if the page was successfullycleaned, or an error value if not. Note that in order to prevent the pagegetting mapped back in and redirtied, it needs to be kept lockedacross the entire operation.	Note: currently almost all instances of address_space methods areusing BKL for internal serialization and that's one of the worst sourcesof contention. Normally they are calling library functions (in fs/buffer.c)and pass foo_get_block() as a callback (on local block-based filesystems,indeed). BKL is not needed for library stuff and is usually taken byfoo_get_block(). It's an overkill, since block bitmaps can be protected byinternal fs locking and real critical areas are much smaller than the areasfilesystems protect now.----------------------- file_lock_operations ------------------------------prototypes:	void (*fl_insert)(struct file_lock *);	/* lock insertion callback */	void (*fl_remove)(struct file_lock *);	/* lock removal callback */	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);	void (*fl_release_private)(struct file_lock *);locking rules:			BKL	may blockfl_insert:		yes	nofl_remove:		yes	nofl_copy_lock:		yes	nofl_release_private:	yes	yes----------------------- lock_manager_operations ---------------------------prototypes:	int (*fl_compare_owner)(struct file_lock *, struct file_lock *);	void (*fl_notify)(struct file_lock *);  /* unblock callback */	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);	void (*fl_release_private)(struct file_lock *);	void (*fl_break)(struct file_lock *); /* break_lease callback */locking rules:			BKL	may blockfl_compare_owner:	yes	nofl_notify:		yes	nofl_copy_lock:		yes	nofl_release_private:	yes	yesfl_break:		yes	no	Currently only NFSD and NLM provide instances of this class. None of thethem block. If you have out-of-tree instances - please, show up. Lockingin that area will change.--------------------------- buffer_head -----------------------------------prototypes:	void (*b_end_io)(struct buffer_head *bh, int uptodate);locking rules:	called from interrupts. In other words, extreme care is needed here.bh is locked, but that's all warranties we have here. Currently only RAID1,highmem, fs/buffer.c, and fs/ntfs/aops.c are providing these. Block devicescall this method upon the IO completion.--------------------------- block_device_operations -----------------------prototypes:	int (*open) (struct inode *, struct file *);	int (*release) (struct inode *, struct file *);	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);	int (*media_changed) (struct gendisk *);	int (*revalidate_disk) (struct gendisk *);locking rules:			BKL	bd_semopen:			yes	yesrelease:		yes	yesioctl:			yes	nomedia_changed:		no	norevalidate_disk:	no	noThe last two are called only from check_disk_change().--------------------------- file_operations -------------------------------prototypes:	loff_t (*llseek) (struct file *, loff_t, int);	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);	int (*readdir) (struct file *, void *, filldir_t);	unsigned int (*poll) (struct file *, struct poll_table_struct *);	int (*ioctl) (struct inode *, struct file *, unsigned int,			unsigned long);	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);	int (*mmap) (struct file *, struct vm_area_struct *);	int (*open) (struct inode *, struct file *);	int (*flush) (struct file *);	int (*release) (struct inode *, struct file *);	int (*fsync) (struct file *, struct dentry *, int datasync);	int (*aio_fsync) (struct kiocb *, int datasync);	int (*fasync) (int, struct file *, int);	int (*lock) (struct file *, int, struct file_lock *);	ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,			loff_t *);	ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,			loff_t *);	ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t,			void __user *);	ssize_t (*sendpage) (struct file *, struct page *, int, size_t,			loff_t *, int);	unsigned long (*get_unmapped_area)(struct file *, unsigned long,			unsigned long, unsigned long, unsigned long);	int (*check_flags)(int);	int (*dir_notify)(struct file *, unsigned long);};locking rules:	All except ->poll() may block.			BKLllseek:			no	(see below)read:			noaio_read:		nowrite:			noaio_write:		noreaddir: 		nopoll:			noioctl:			yes	(see below)unlocked_ioctl:		no	(see below)compat_ioctl:		nommap:			noopen:			maybe	(see below)flush:			norelease:		nofsync:			no	(see below)aio_fsync:		nofasync:			yes	(see below)lock:			yesreadv:			nowritev:			nosendfile:		nosendpage:		noget_unmapped_area:	nocheck_flags:		nodir_notify:		no->llseek() locking has moved from llseek to the individual llseekimplementations.  If your fs is not using generic_file_llseek, youneed to acquire and release the appropriate locks in your ->llseek().For many filesystems, it is probably safe to acquire the inodesemaphore.  Note some filesystems (i.e. remote ones) provide noprotection for i_size so you will need to use the BKL.->open() locking is in-transit: big lock partially moved into the methods.The only exception is ->open() in the instances of file_operations that neverend up in ->i_fop/->proc_fops, i.e. ones that belong to character devices(chrdev_open() takes lock before replacing ->f_op and calling the secondarymethod. As soon as we fix the handling of module reference counters allinstances of ->open() will be called without the BKL.Note: ext2_release() was *the* source of contention on fs-intensiveloads and dropping BKL on ->release() helps to get rid of that (we stillgrab BKL for cases when we close a file that had been opened r/w, but thatcan and should be done using the internal locking with smaller critical areas).Current worst offender is ext2_get_block()...->fasync() is a mess. This area needs a big cleanup and that will probablyaffect locking.->readdir() and ->ioctl() on directories must be changed. Ideally we wouldmove ->readdir() to inode_operations and use a separate method for directory->ioctl() or kill the latter completely. One of the problems is that foranything that resembles union-mount we won't have a struct file for allcomponents. And there are other reasons why the current interface is a mess...->ioctl() on regular files is superceded by the ->unlocked_ioctl() thatdoesn't take the BKL.->read on directories probably must go away - we should just enforce -EISDIRin sys_read() and friends.->fsync() has i_mutex on inode.--------------------------- dquot_operations -------------------------------prototypes:	int (*initialize) (struct inode *, int);	int (*drop) (struct inode *);	int (*alloc_space) (struct inode *, qsize_t, int);	int (*alloc_inode) (const struct inode *, unsigned long);	int (*free_space) (struct inode *, qsize_t);	int (*free_inode) (const struct inode *, unsigned long);	int (*transfer) (struct inode *, struct iattr *);	int (*write_dquot) (struct dquot *);	int (*acquire_dquot) (struct dquot *);	int (*release_dquot) (struct dquot *);	int (*mark_dirty) (struct dquot *);	int (*write_info) (struct super_block *, int);These operations are intended to be more or less wrapping functions that ensurea proper locking wrt the filesystem and call the generic quota operations.What filesystem should expect from the generic quota functions:		FS recursion	Held locks when calledinitialize:	yes		maybe dqonoff_semdrop:		yes		-alloc_space:	->mark_dirty()	-alloc_inode:	->mark_dirty()	-free_space:	->mark_dirty()	-free_inode:	->mark_dirty()	-transfer:	yes		-write_dquot:	yes		dqonoff_sem or dqptr_semacquire_dquot:	yes		dqonoff_sem or dqptr_semrelease_dquot:	yes		dqonoff_sem or dqptr_semmark_dirty:	no		-write_info:	yes		dqonoff_semFS recursion means calling ->quota_read() and ->quota_write() from superblockoperations.->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are calledonly directly by the filesystem and do not call any fs functions onlythe ->mark_dirty() operation.More details about quota locking can be found in fs/dquot.c.--------------------------- vm_operations_struct -----------------------------prototypes:	void (*open)(struct vm_area_struct*);	void (*close)(struct vm_area_struct*);	int (*fault)(struct vm_area_struct*, struct vm_fault *);	struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *);	int (*page_mkwrite)(struct vm_area_struct *, struct page *);locking rules:		BKL	mmap_sem	PageLocked(page)open:		no	yesclose:		no	yesfault:		no	yesnopage:		no	yespage_mkwrite:	no	yes		no	->page_mkwrite() is called when a previously read-only page isabout to become writeable. The file system is responsible forprotecting against truncate races. Once appropriate action has beentaking to lock out truncate, the page range should be verified to bewithin i_size. The page mapping should also be checked that it is notNULL.================================================================================			Dubious stuff(if you break something or notice that it is broken and do not fix it yourself- at least put it here)ipc/shm.c::shm_delete() - may need BKL.->read() and ->write() in many drivers are (probably) missing BKL.drivers/sgi/char/graphics.c::sgi_graphics_nopage() - may need BKL.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -