diff options
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r-- | include/linux/fs.h | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 42efe13077b6..ec0f1dc66b9b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/byteorder.h> | 34 | #include <asm/byteorder.h> |
35 | #include <uapi/linux/fs.h> | 35 | #include <uapi/linux/fs.h> |
36 | 36 | ||
37 | struct backing_dev_info; | ||
37 | struct export_operations; | 38 | struct export_operations; |
38 | struct hd_geometry; | 39 | struct hd_geometry; |
39 | struct iovec; | 40 | struct iovec; |
@@ -394,14 +395,12 @@ int pagecache_write_end(struct file *, struct address_space *mapping, | |||
394 | loff_t pos, unsigned len, unsigned copied, | 395 | loff_t pos, unsigned len, unsigned copied, |
395 | struct page *page, void *fsdata); | 396 | struct page *page, void *fsdata); |
396 | 397 | ||
397 | struct backing_dev_info; | ||
398 | struct address_space { | 398 | struct address_space { |
399 | struct inode *host; /* owner: inode, block_device */ | 399 | struct inode *host; /* owner: inode, block_device */ |
400 | struct radix_tree_root page_tree; /* radix tree of all pages */ | 400 | struct radix_tree_root page_tree; /* radix tree of all pages */ |
401 | spinlock_t tree_lock; /* and lock protecting it */ | 401 | spinlock_t tree_lock; /* and lock protecting it */ |
402 | atomic_t i_mmap_writable;/* count VM_SHARED mappings */ | 402 | atomic_t i_mmap_writable;/* count VM_SHARED mappings */ |
403 | struct rb_root i_mmap; /* tree of private and shared mappings */ | 403 | struct rb_root i_mmap; /* tree of private and shared mappings */ |
404 | struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ | ||
405 | struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */ | 404 | struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */ |
406 | /* Protected by tree_lock together with the radix tree */ | 405 | /* Protected by tree_lock together with the radix tree */ |
407 | unsigned long nrpages; /* number of total pages */ | 406 | unsigned long nrpages; /* number of total pages */ |
@@ -409,7 +408,6 @@ struct address_space { | |||
409 | pgoff_t writeback_index;/* writeback starts here */ | 408 | pgoff_t writeback_index;/* writeback starts here */ |
410 | const struct address_space_operations *a_ops; /* methods */ | 409 | const struct address_space_operations *a_ops; /* methods */ |
411 | unsigned long flags; /* error bits/gfp mask */ | 410 | unsigned long flags; /* error bits/gfp mask */ |
412 | struct backing_dev_info *backing_dev_info; /* device readahead, etc */ | ||
413 | spinlock_t private_lock; /* for use by the address_space */ | 411 | spinlock_t private_lock; /* for use by the address_space */ |
414 | struct list_head private_list; /* ditto */ | 412 | struct list_head private_list; /* ditto */ |
415 | void *private_data; /* ditto */ | 413 | void *private_data; /* ditto */ |
@@ -493,8 +491,7 @@ static inline void i_mmap_unlock_read(struct address_space *mapping) | |||
493 | */ | 491 | */ |
494 | static inline int mapping_mapped(struct address_space *mapping) | 492 | static inline int mapping_mapped(struct address_space *mapping) |
495 | { | 493 | { |
496 | return !RB_EMPTY_ROOT(&mapping->i_mmap) || | 494 | return !RB_EMPTY_ROOT(&mapping->i_mmap); |
497 | !list_empty(&mapping->i_mmap_nonlinear); | ||
498 | } | 495 | } |
499 | 496 | ||
500 | /* | 497 | /* |
@@ -625,7 +622,7 @@ struct inode { | |||
625 | atomic_t i_readcount; /* struct files open RO */ | 622 | atomic_t i_readcount; /* struct files open RO */ |
626 | #endif | 623 | #endif |
627 | const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ | 624 | const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ |
628 | struct file_lock *i_flock; | 625 | struct file_lock_context *i_flctx; |
629 | struct address_space i_data; | 626 | struct address_space i_data; |
630 | struct list_head i_devices; | 627 | struct list_head i_devices; |
631 | union { | 628 | union { |
@@ -875,6 +872,7 @@ static inline struct file *get_file(struct file *f) | |||
875 | #define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ | 872 | #define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ |
876 | #define FL_UNLOCK_PENDING 512 /* Lease is being broken */ | 873 | #define FL_UNLOCK_PENDING 512 /* Lease is being broken */ |
877 | #define FL_OFDLCK 1024 /* lock is "owned" by struct file */ | 874 | #define FL_OFDLCK 1024 /* lock is "owned" by struct file */ |
875 | #define FL_LAYOUT 2048 /* outstanding pNFS layout */ | ||
878 | 876 | ||
879 | /* | 877 | /* |
880 | * Special return value from posix_lock_file() and vfs_lock_file() for | 878 | * Special return value from posix_lock_file() and vfs_lock_file() for |
@@ -885,6 +883,8 @@ static inline struct file *get_file(struct file *f) | |||
885 | /* legacy typedef, should eventually be removed */ | 883 | /* legacy typedef, should eventually be removed */ |
886 | typedef void *fl_owner_t; | 884 | typedef void *fl_owner_t; |
887 | 885 | ||
886 | struct file_lock; | ||
887 | |||
888 | struct file_lock_operations { | 888 | struct file_lock_operations { |
889 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); | 889 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); |
890 | void (*fl_release_private)(struct file_lock *); | 890 | void (*fl_release_private)(struct file_lock *); |
@@ -898,7 +898,7 @@ struct lock_manager_operations { | |||
898 | void (*lm_notify)(struct file_lock *); /* unblock callback */ | 898 | void (*lm_notify)(struct file_lock *); /* unblock callback */ |
899 | int (*lm_grant)(struct file_lock *, int); | 899 | int (*lm_grant)(struct file_lock *, int); |
900 | bool (*lm_break)(struct file_lock *); | 900 | bool (*lm_break)(struct file_lock *); |
901 | int (*lm_change)(struct file_lock **, int, struct list_head *); | 901 | int (*lm_change)(struct file_lock *, int, struct list_head *); |
902 | void (*lm_setup)(struct file_lock *, void **); | 902 | void (*lm_setup)(struct file_lock *, void **); |
903 | }; | 903 | }; |
904 | 904 | ||
@@ -923,17 +923,17 @@ int locks_in_grace(struct net *); | |||
923 | * FIXME: should we create a separate "struct lock_request" to help distinguish | 923 | * FIXME: should we create a separate "struct lock_request" to help distinguish |
924 | * these two uses? | 924 | * these two uses? |
925 | * | 925 | * |
926 | * The i_flock list is ordered by: | 926 | * The varous i_flctx lists are ordered by: |
927 | * | 927 | * |
928 | * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX | 928 | * 1) lock owner |
929 | * 2) lock owner | 929 | * 2) lock range start |
930 | * 3) lock range start | 930 | * 3) lock range end |
931 | * 4) lock range end | ||
932 | * | 931 | * |
933 | * Obviously, the last two criteria only matter for POSIX locks. | 932 | * Obviously, the last two criteria only matter for POSIX locks. |
934 | */ | 933 | */ |
935 | struct file_lock { | 934 | struct file_lock { |
936 | struct file_lock *fl_next; /* singly linked list for this inode */ | 935 | struct file_lock *fl_next; /* singly linked list for this inode */ |
936 | struct list_head fl_list; /* link into file_lock_context */ | ||
937 | struct hlist_node fl_link; /* node in global lists */ | 937 | struct hlist_node fl_link; /* node in global lists */ |
938 | struct list_head fl_block; /* circular list of blocked processes */ | 938 | struct list_head fl_block; /* circular list of blocked processes */ |
939 | fl_owner_t fl_owner; | 939 | fl_owner_t fl_owner; |
@@ -964,6 +964,16 @@ struct file_lock { | |||
964 | } fl_u; | 964 | } fl_u; |
965 | }; | 965 | }; |
966 | 966 | ||
967 | struct file_lock_context { | ||
968 | spinlock_t flc_lock; | ||
969 | struct list_head flc_flock; | ||
970 | struct list_head flc_posix; | ||
971 | struct list_head flc_lease; | ||
972 | int flc_flock_cnt; | ||
973 | int flc_posix_cnt; | ||
974 | int flc_lease_cnt; | ||
975 | }; | ||
976 | |||
967 | /* The following constant reflects the upper bound of the file/locking space */ | 977 | /* The following constant reflects the upper bound of the file/locking space */ |
968 | #ifndef OFFSET_MAX | 978 | #ifndef OFFSET_MAX |
969 | #define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1))) | 979 | #define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1))) |
@@ -990,6 +1000,7 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); | |||
990 | extern int fcntl_getlease(struct file *filp); | 1000 | extern int fcntl_getlease(struct file *filp); |
991 | 1001 | ||
992 | /* fs/locks.c */ | 1002 | /* fs/locks.c */ |
1003 | void locks_free_lock_context(struct file_lock_context *ctx); | ||
993 | void locks_free_lock(struct file_lock *fl); | 1004 | void locks_free_lock(struct file_lock *fl); |
994 | extern void locks_init_lock(struct file_lock *); | 1005 | extern void locks_init_lock(struct file_lock *); |
995 | extern struct file_lock * locks_alloc_lock(void); | 1006 | extern struct file_lock * locks_alloc_lock(void); |
@@ -1010,7 +1021,7 @@ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int t | |||
1010 | extern void lease_get_mtime(struct inode *, struct timespec *time); | 1021 | extern void lease_get_mtime(struct inode *, struct timespec *time); |
1011 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); | 1022 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); |
1012 | extern int vfs_setlease(struct file *, long, struct file_lock **, void **); | 1023 | extern int vfs_setlease(struct file *, long, struct file_lock **, void **); |
1013 | extern int lease_modify(struct file_lock **, int, struct list_head *); | 1024 | extern int lease_modify(struct file_lock *, int, struct list_head *); |
1014 | #else /* !CONFIG_FILE_LOCKING */ | 1025 | #else /* !CONFIG_FILE_LOCKING */ |
1015 | static inline int fcntl_getlk(struct file *file, unsigned int cmd, | 1026 | static inline int fcntl_getlk(struct file *file, unsigned int cmd, |
1016 | struct flock __user *user) | 1027 | struct flock __user *user) |
@@ -1047,6 +1058,11 @@ static inline int fcntl_getlease(struct file *filp) | |||
1047 | return F_UNLCK; | 1058 | return F_UNLCK; |
1048 | } | 1059 | } |
1049 | 1060 | ||
1061 | static inline void | ||
1062 | locks_free_lock_context(struct file_lock_context *ctx) | ||
1063 | { | ||
1064 | } | ||
1065 | |||
1050 | static inline void locks_init_lock(struct file_lock *fl) | 1066 | static inline void locks_init_lock(struct file_lock *fl) |
1051 | { | 1067 | { |
1052 | return; | 1068 | return; |
@@ -1137,7 +1153,7 @@ static inline int vfs_setlease(struct file *filp, long arg, | |||
1137 | return -EINVAL; | 1153 | return -EINVAL; |
1138 | } | 1154 | } |
1139 | 1155 | ||
1140 | static inline int lease_modify(struct file_lock **before, int arg, | 1156 | static inline int lease_modify(struct file_lock *fl, int arg, |
1141 | struct list_head *dispose) | 1157 | struct list_head *dispose) |
1142 | { | 1158 | { |
1143 | return -EINVAL; | 1159 | return -EINVAL; |
@@ -1184,8 +1200,6 @@ struct mm_struct; | |||
1184 | #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ | 1200 | #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ |
1185 | #define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */ | 1201 | #define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */ |
1186 | 1202 | ||
1187 | extern struct list_head super_blocks; | ||
1188 | extern spinlock_t sb_lock; | ||
1189 | 1203 | ||
1190 | /* Possible states of 'frozen' field */ | 1204 | /* Possible states of 'frozen' field */ |
1191 | enum { | 1205 | enum { |
@@ -1502,6 +1516,26 @@ struct block_device_operations; | |||
1502 | #define HAVE_COMPAT_IOCTL 1 | 1516 | #define HAVE_COMPAT_IOCTL 1 |
1503 | #define HAVE_UNLOCKED_IOCTL 1 | 1517 | #define HAVE_UNLOCKED_IOCTL 1 |
1504 | 1518 | ||
1519 | /* | ||
1520 | * These flags let !MMU mmap() govern direct device mapping vs immediate | ||
1521 | * copying more easily for MAP_PRIVATE, especially for ROM filesystems. | ||
1522 | * | ||
1523 | * NOMMU_MAP_COPY: Copy can be mapped (MAP_PRIVATE) | ||
1524 | * NOMMU_MAP_DIRECT: Can be mapped directly (MAP_SHARED) | ||
1525 | * NOMMU_MAP_READ: Can be mapped for reading | ||
1526 | * NOMMU_MAP_WRITE: Can be mapped for writing | ||
1527 | * NOMMU_MAP_EXEC: Can be mapped for execution | ||
1528 | */ | ||
1529 | #define NOMMU_MAP_COPY 0x00000001 | ||
1530 | #define NOMMU_MAP_DIRECT 0x00000008 | ||
1531 | #define NOMMU_MAP_READ VM_MAYREAD | ||
1532 | #define NOMMU_MAP_WRITE VM_MAYWRITE | ||
1533 | #define NOMMU_MAP_EXEC VM_MAYEXEC | ||
1534 | |||
1535 | #define NOMMU_VMFLAGS \ | ||
1536 | (NOMMU_MAP_READ | NOMMU_MAP_WRITE | NOMMU_MAP_EXEC) | ||
1537 | |||
1538 | |||
1505 | struct iov_iter; | 1539 | struct iov_iter; |
1506 | 1540 | ||
1507 | struct file_operations { | 1541 | struct file_operations { |
@@ -1536,6 +1570,9 @@ struct file_operations { | |||
1536 | long (*fallocate)(struct file *file, int mode, loff_t offset, | 1570 | long (*fallocate)(struct file *file, int mode, loff_t offset, |
1537 | loff_t len); | 1571 | loff_t len); |
1538 | void (*show_fdinfo)(struct seq_file *m, struct file *f); | 1572 | void (*show_fdinfo)(struct seq_file *m, struct file *f); |
1573 | #ifndef CONFIG_MMU | ||
1574 | unsigned (*mmap_capabilities)(struct file *); | ||
1575 | #endif | ||
1539 | }; | 1576 | }; |
1540 | 1577 | ||
1541 | struct inode_operations { | 1578 | struct inode_operations { |
@@ -1959,7 +1996,7 @@ static inline int locks_verify_truncate(struct inode *inode, | |||
1959 | struct file *filp, | 1996 | struct file *filp, |
1960 | loff_t size) | 1997 | loff_t size) |
1961 | { | 1998 | { |
1962 | if (inode->i_flock && mandatory_lock(inode)) | 1999 | if (inode->i_flctx && mandatory_lock(inode)) |
1963 | return locks_mandatory_area( | 2000 | return locks_mandatory_area( |
1964 | FLOCK_VERIFY_WRITE, inode, filp, | 2001 | FLOCK_VERIFY_WRITE, inode, filp, |
1965 | size < inode->i_size ? size : inode->i_size, | 2002 | size < inode->i_size ? size : inode->i_size, |
@@ -1973,11 +2010,12 @@ static inline int break_lease(struct inode *inode, unsigned int mode) | |||
1973 | { | 2010 | { |
1974 | /* | 2011 | /* |
1975 | * Since this check is lockless, we must ensure that any refcounts | 2012 | * Since this check is lockless, we must ensure that any refcounts |
1976 | * taken are done before checking inode->i_flock. Otherwise, we could | 2013 | * taken are done before checking i_flctx->flc_lease. Otherwise, we |
1977 | * end up racing with tasks trying to set a new lease on this file. | 2014 | * could end up racing with tasks trying to set a new lease on this |
2015 | * file. | ||
1978 | */ | 2016 | */ |
1979 | smp_mb(); | 2017 | smp_mb(); |
1980 | if (inode->i_flock) | 2018 | if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) |
1981 | return __break_lease(inode, mode, FL_LEASE); | 2019 | return __break_lease(inode, mode, FL_LEASE); |
1982 | return 0; | 2020 | return 0; |
1983 | } | 2021 | } |
@@ -1986,11 +2024,12 @@ static inline int break_deleg(struct inode *inode, unsigned int mode) | |||
1986 | { | 2024 | { |
1987 | /* | 2025 | /* |
1988 | * Since this check is lockless, we must ensure that any refcounts | 2026 | * Since this check is lockless, we must ensure that any refcounts |
1989 | * taken are done before checking inode->i_flock. Otherwise, we could | 2027 | * taken are done before checking i_flctx->flc_lease. Otherwise, we |
1990 | * end up racing with tasks trying to set a new lease on this file. | 2028 | * could end up racing with tasks trying to set a new lease on this |
2029 | * file. | ||
1991 | */ | 2030 | */ |
1992 | smp_mb(); | 2031 | smp_mb(); |
1993 | if (inode->i_flock) | 2032 | if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) |
1994 | return __break_lease(inode, mode, FL_DELEG); | 2033 | return __break_lease(inode, mode, FL_DELEG); |
1995 | return 0; | 2034 | return 0; |
1996 | } | 2035 | } |
@@ -2017,6 +2056,16 @@ static inline int break_deleg_wait(struct inode **delegated_inode) | |||
2017 | return ret; | 2056 | return ret; |
2018 | } | 2057 | } |
2019 | 2058 | ||
2059 | static inline int break_layout(struct inode *inode, bool wait) | ||
2060 | { | ||
2061 | smp_mb(); | ||
2062 | if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) | ||
2063 | return __break_lease(inode, | ||
2064 | wait ? O_WRONLY : O_WRONLY | O_NONBLOCK, | ||
2065 | FL_LAYOUT); | ||
2066 | return 0; | ||
2067 | } | ||
2068 | |||
2020 | #else /* !CONFIG_FILE_LOCKING */ | 2069 | #else /* !CONFIG_FILE_LOCKING */ |
2021 | static inline int locks_mandatory_locked(struct file *file) | 2070 | static inline int locks_mandatory_locked(struct file *file) |
2022 | { | 2071 | { |
@@ -2072,6 +2121,11 @@ static inline int break_deleg_wait(struct inode **delegated_inode) | |||
2072 | return 0; | 2121 | return 0; |
2073 | } | 2122 | } |
2074 | 2123 | ||
2124 | static inline int break_layout(struct inode *inode, bool wait) | ||
2125 | { | ||
2126 | return 0; | ||
2127 | } | ||
2128 | |||
2075 | #endif /* CONFIG_FILE_LOCKING */ | 2129 | #endif /* CONFIG_FILE_LOCKING */ |
2076 | 2130 | ||
2077 | /* fs/open.c */ | 2131 | /* fs/open.c */ |
@@ -2481,8 +2535,6 @@ extern int sb_min_blocksize(struct super_block *, int); | |||
2481 | 2535 | ||
2482 | extern int generic_file_mmap(struct file *, struct vm_area_struct *); | 2536 | extern int generic_file_mmap(struct file *, struct vm_area_struct *); |
2483 | extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); | 2537 | extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); |
2484 | extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr, | ||
2485 | unsigned long size, pgoff_t pgoff); | ||
2486 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); | 2538 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); |
2487 | extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); | 2539 | extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); |
2488 | extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); | 2540 | extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); |