xref: /linux-6.15/include/linux/backing-dev.h (revision 3fcfab16)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * include/linux/backing-dev.h
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * low-level device information and state which is propagated up through
51da177e4SLinus Torvalds  * to high-level code.
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #ifndef _LINUX_BACKING_DEV_H
91da177e4SLinus Torvalds #define _LINUX_BACKING_DEV_H
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <asm/atomic.h>
121da177e4SLinus Torvalds 
13*3fcfab16SAndrew Morton struct page;
14*3fcfab16SAndrew Morton 
151da177e4SLinus Torvalds /*
161da177e4SLinus Torvalds  * Bits in backing_dev_info.state
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds enum bdi_state {
191da177e4SLinus Torvalds 	BDI_pdflush,		/* A pdflush thread is working this device */
201da177e4SLinus Torvalds 	BDI_write_congested,	/* The write queue is getting full */
211da177e4SLinus Torvalds 	BDI_read_congested,	/* The read queue is getting full */
221da177e4SLinus Torvalds 	BDI_unused,		/* Available bits start here */
231da177e4SLinus Torvalds };
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds typedef int (congested_fn)(void *, int);
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds struct backing_dev_info {
281da177e4SLinus Torvalds 	unsigned long ra_pages;	/* max readahead in PAGE_CACHE_SIZE units */
291da177e4SLinus Torvalds 	unsigned long state;	/* Always use atomic bitops on this */
301da177e4SLinus Torvalds 	unsigned int capabilities; /* Device capabilities */
311da177e4SLinus Torvalds 	congested_fn *congested_fn; /* Function pointer if device is md/dm */
321da177e4SLinus Torvalds 	void *congested_data;	/* Pointer to aux data for congested func */
331da177e4SLinus Torvalds 	void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
341da177e4SLinus Torvalds 	void *unplug_io_data;
351da177e4SLinus Torvalds };
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds /*
391da177e4SLinus Torvalds  * Flags in backing_dev_info::capability
401da177e4SLinus Torvalds  * - The first two flags control whether dirty pages will contribute to the
411da177e4SLinus Torvalds  *   VM's accounting and whether writepages() should be called for dirty pages
421da177e4SLinus Torvalds  *   (something that would not, for example, be appropriate for ramfs)
431da177e4SLinus Torvalds  * - These flags let !MMU mmap() govern direct device mapping vs immediate
441da177e4SLinus Torvalds  *   copying more easily for MAP_PRIVATE, especially for ROM filesystems
451da177e4SLinus Torvalds  */
461da177e4SLinus Torvalds #define BDI_CAP_NO_ACCT_DIRTY	0x00000001	/* Dirty pages shouldn't contribute to accounting */
471da177e4SLinus Torvalds #define BDI_CAP_NO_WRITEBACK	0x00000002	/* Don't write pages back */
481da177e4SLinus Torvalds #define BDI_CAP_MAP_COPY	0x00000004	/* Copy can be mapped (MAP_PRIVATE) */
491da177e4SLinus Torvalds #define BDI_CAP_MAP_DIRECT	0x00000008	/* Can be mapped directly (MAP_SHARED) */
501da177e4SLinus Torvalds #define BDI_CAP_READ_MAP	0x00000010	/* Can be mapped for reading */
511da177e4SLinus Torvalds #define BDI_CAP_WRITE_MAP	0x00000020	/* Can be mapped for writing */
521da177e4SLinus Torvalds #define BDI_CAP_EXEC_MAP	0x00000040	/* Can be mapped for execution */
531da177e4SLinus Torvalds #define BDI_CAP_VMFLAGS \
541da177e4SLinus Torvalds 	(BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds #if defined(VM_MAYREAD) && \
571da177e4SLinus Torvalds 	(BDI_CAP_READ_MAP != VM_MAYREAD || \
581da177e4SLinus Torvalds 	 BDI_CAP_WRITE_MAP != VM_MAYWRITE || \
591da177e4SLinus Torvalds 	 BDI_CAP_EXEC_MAP != VM_MAYEXEC)
601da177e4SLinus Torvalds #error please change backing_dev_info::capabilities flags
611da177e4SLinus Torvalds #endif
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds extern struct backing_dev_info default_backing_dev_info;
641da177e4SLinus Torvalds void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds int writeback_acquire(struct backing_dev_info *bdi);
671da177e4SLinus Torvalds int writeback_in_progress(struct backing_dev_info *bdi);
681da177e4SLinus Torvalds void writeback_release(struct backing_dev_info *bdi);
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
711da177e4SLinus Torvalds {
721da177e4SLinus Torvalds 	if (bdi->congested_fn)
731da177e4SLinus Torvalds 		return bdi->congested_fn(bdi->congested_data, bdi_bits);
741da177e4SLinus Torvalds 	return (bdi->state & bdi_bits);
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds static inline int bdi_read_congested(struct backing_dev_info *bdi)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds 	return bdi_congested(bdi, 1 << BDI_read_congested);
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds static inline int bdi_write_congested(struct backing_dev_info *bdi)
831da177e4SLinus Torvalds {
841da177e4SLinus Torvalds 	return bdi_congested(bdi, 1 << BDI_write_congested);
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds static inline int bdi_rw_congested(struct backing_dev_info *bdi)
881da177e4SLinus Torvalds {
891da177e4SLinus Torvalds 	return bdi_congested(bdi, (1 << BDI_read_congested)|
901da177e4SLinus Torvalds 				  (1 << BDI_write_congested));
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
93*3fcfab16SAndrew Morton void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
94*3fcfab16SAndrew Morton void set_bdi_congested(struct backing_dev_info *bdi, int rw);
95*3fcfab16SAndrew Morton long congestion_wait(int rw, long timeout);
96*3fcfab16SAndrew Morton void congestion_end(int rw);
97*3fcfab16SAndrew Morton 
981da177e4SLinus Torvalds #define bdi_cap_writeback_dirty(bdi) \
991da177e4SLinus Torvalds 	(!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds #define bdi_cap_account_dirty(bdi) \
1021da177e4SLinus Torvalds 	(!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY))
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds #define mapping_cap_writeback_dirty(mapping) \
1051da177e4SLinus Torvalds 	bdi_cap_writeback_dirty((mapping)->backing_dev_info)
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds #define mapping_cap_account_dirty(mapping) \
1081da177e4SLinus Torvalds 	bdi_cap_account_dirty((mapping)->backing_dev_info)
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds #endif		/* _LINUX_BACKING_DEV_H */
112