diff options
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r-- | include/linux/fs.h | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 090f0eacde29..baf3e556ff0e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -392,6 +392,7 @@ struct inodes_stat_t { | |||
392 | #include <linux/capability.h> | 392 | #include <linux/capability.h> |
393 | #include <linux/semaphore.h> | 393 | #include <linux/semaphore.h> |
394 | #include <linux/fiemap.h> | 394 | #include <linux/fiemap.h> |
395 | #include <linux/rculist_bl.h> | ||
395 | 396 | ||
396 | #include <asm/atomic.h> | 397 | #include <asm/atomic.h> |
397 | #include <asm/byteorder.h> | 398 | #include <asm/byteorder.h> |
@@ -733,16 +734,31 @@ struct posix_acl; | |||
733 | #define ACL_NOT_CACHED ((void *)(-1)) | 734 | #define ACL_NOT_CACHED ((void *)(-1)) |
734 | 735 | ||
735 | struct inode { | 736 | struct inode { |
737 | /* RCU path lookup touches following: */ | ||
738 | umode_t i_mode; | ||
739 | uid_t i_uid; | ||
740 | gid_t i_gid; | ||
741 | const struct inode_operations *i_op; | ||
742 | struct super_block *i_sb; | ||
743 | |||
744 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ | ||
745 | unsigned int i_flags; | ||
746 | struct mutex i_mutex; | ||
747 | |||
748 | unsigned long i_state; | ||
749 | unsigned long dirtied_when; /* jiffies of first dirtying */ | ||
750 | |||
736 | struct hlist_node i_hash; | 751 | struct hlist_node i_hash; |
737 | struct list_head i_wb_list; /* backing dev IO list */ | 752 | struct list_head i_wb_list; /* backing dev IO list */ |
738 | struct list_head i_lru; /* inode LRU list */ | 753 | struct list_head i_lru; /* inode LRU list */ |
739 | struct list_head i_sb_list; | 754 | struct list_head i_sb_list; |
740 | struct list_head i_dentry; | 755 | union { |
756 | struct list_head i_dentry; | ||
757 | struct rcu_head i_rcu; | ||
758 | }; | ||
741 | unsigned long i_ino; | 759 | unsigned long i_ino; |
742 | atomic_t i_count; | 760 | atomic_t i_count; |
743 | unsigned int i_nlink; | 761 | unsigned int i_nlink; |
744 | uid_t i_uid; | ||
745 | gid_t i_gid; | ||
746 | dev_t i_rdev; | 762 | dev_t i_rdev; |
747 | unsigned int i_blkbits; | 763 | unsigned int i_blkbits; |
748 | u64 i_version; | 764 | u64 i_version; |
@@ -755,13 +771,8 @@ struct inode { | |||
755 | struct timespec i_ctime; | 771 | struct timespec i_ctime; |
756 | blkcnt_t i_blocks; | 772 | blkcnt_t i_blocks; |
757 | unsigned short i_bytes; | 773 | unsigned short i_bytes; |
758 | umode_t i_mode; | ||
759 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ | ||
760 | struct mutex i_mutex; | ||
761 | struct rw_semaphore i_alloc_sem; | 774 | struct rw_semaphore i_alloc_sem; |
762 | const struct inode_operations *i_op; | ||
763 | const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ | 775 | const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ |
764 | struct super_block *i_sb; | ||
765 | struct file_lock *i_flock; | 776 | struct file_lock *i_flock; |
766 | struct address_space *i_mapping; | 777 | struct address_space *i_mapping; |
767 | struct address_space i_data; | 778 | struct address_space i_data; |
@@ -782,11 +793,6 @@ struct inode { | |||
782 | struct hlist_head i_fsnotify_marks; | 793 | struct hlist_head i_fsnotify_marks; |
783 | #endif | 794 | #endif |
784 | 795 | ||
785 | unsigned long i_state; | ||
786 | unsigned long dirtied_when; /* jiffies of first dirtying */ | ||
787 | |||
788 | unsigned int i_flags; | ||
789 | |||
790 | #ifdef CONFIG_IMA | 796 | #ifdef CONFIG_IMA |
791 | /* protected by i_lock */ | 797 | /* protected by i_lock */ |
792 | unsigned int i_readcount; /* struct files open RO */ | 798 | unsigned int i_readcount; /* struct files open RO */ |
@@ -1372,13 +1378,13 @@ struct super_block { | |||
1372 | const struct xattr_handler **s_xattr; | 1378 | const struct xattr_handler **s_xattr; |
1373 | 1379 | ||
1374 | struct list_head s_inodes; /* all inodes */ | 1380 | struct list_head s_inodes; /* all inodes */ |
1375 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ | 1381 | struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ |
1376 | #ifdef CONFIG_SMP | 1382 | #ifdef CONFIG_SMP |
1377 | struct list_head __percpu *s_files; | 1383 | struct list_head __percpu *s_files; |
1378 | #else | 1384 | #else |
1379 | struct list_head s_files; | 1385 | struct list_head s_files; |
1380 | #endif | 1386 | #endif |
1381 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ | 1387 | /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */ |
1382 | struct list_head s_dentry_lru; /* unused dentry lru */ | 1388 | struct list_head s_dentry_lru; /* unused dentry lru */ |
1383 | int s_nr_dentry_unused; /* # of dentry on lru */ | 1389 | int s_nr_dentry_unused; /* # of dentry on lru */ |
1384 | 1390 | ||
@@ -1545,9 +1551,18 @@ struct file_operations { | |||
1545 | int (*setlease)(struct file *, long, struct file_lock **); | 1551 | int (*setlease)(struct file *, long, struct file_lock **); |
1546 | }; | 1552 | }; |
1547 | 1553 | ||
1554 | #define IPERM_FLAG_RCU 0x0001 | ||
1555 | |||
1548 | struct inode_operations { | 1556 | struct inode_operations { |
1549 | int (*create) (struct inode *,struct dentry *,int, struct nameidata *); | ||
1550 | struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); | 1557 | struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); |
1558 | void * (*follow_link) (struct dentry *, struct nameidata *); | ||
1559 | int (*permission) (struct inode *, int, unsigned int); | ||
1560 | int (*check_acl)(struct inode *, int, unsigned int); | ||
1561 | |||
1562 | int (*readlink) (struct dentry *, char __user *,int); | ||
1563 | void (*put_link) (struct dentry *, struct nameidata *, void *); | ||
1564 | |||
1565 | int (*create) (struct inode *,struct dentry *,int, struct nameidata *); | ||
1551 | int (*link) (struct dentry *,struct inode *,struct dentry *); | 1566 | int (*link) (struct dentry *,struct inode *,struct dentry *); |
1552 | int (*unlink) (struct inode *,struct dentry *); | 1567 | int (*unlink) (struct inode *,struct dentry *); |
1553 | int (*symlink) (struct inode *,struct dentry *,const char *); | 1568 | int (*symlink) (struct inode *,struct dentry *,const char *); |
@@ -1556,12 +1571,7 @@ struct inode_operations { | |||
1556 | int (*mknod) (struct inode *,struct dentry *,int,dev_t); | 1571 | int (*mknod) (struct inode *,struct dentry *,int,dev_t); |
1557 | int (*rename) (struct inode *, struct dentry *, | 1572 | int (*rename) (struct inode *, struct dentry *, |
1558 | struct inode *, struct dentry *); | 1573 | struct inode *, struct dentry *); |
1559 | int (*readlink) (struct dentry *, char __user *,int); | ||
1560 | void * (*follow_link) (struct dentry *, struct nameidata *); | ||
1561 | void (*put_link) (struct dentry *, struct nameidata *, void *); | ||
1562 | void (*truncate) (struct inode *); | 1574 | void (*truncate) (struct inode *); |
1563 | int (*permission) (struct inode *, int); | ||
1564 | int (*check_acl)(struct inode *, int); | ||
1565 | int (*setattr) (struct dentry *, struct iattr *); | 1575 | int (*setattr) (struct dentry *, struct iattr *); |
1566 | int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); | 1576 | int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); |
1567 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); | 1577 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); |
@@ -1573,7 +1583,7 @@ struct inode_operations { | |||
1573 | loff_t len); | 1583 | loff_t len); |
1574 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, | 1584 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, |
1575 | u64 len); | 1585 | u64 len); |
1576 | }; | 1586 | } ____cacheline_aligned; |
1577 | 1587 | ||
1578 | struct seq_file; | 1588 | struct seq_file; |
1579 | 1589 | ||
@@ -2158,8 +2168,8 @@ extern sector_t bmap(struct inode *, sector_t); | |||
2158 | #endif | 2168 | #endif |
2159 | extern int notify_change(struct dentry *, struct iattr *); | 2169 | extern int notify_change(struct dentry *, struct iattr *); |
2160 | extern int inode_permission(struct inode *, int); | 2170 | extern int inode_permission(struct inode *, int); |
2161 | extern int generic_permission(struct inode *, int, | 2171 | extern int generic_permission(struct inode *, int, unsigned int, |
2162 | int (*check_acl)(struct inode *, int)); | 2172 | int (*check_acl)(struct inode *, int, unsigned int)); |
2163 | 2173 | ||
2164 | static inline bool execute_ok(struct inode *inode) | 2174 | static inline bool execute_ok(struct inode *inode) |
2165 | { | 2175 | { |
@@ -2230,6 +2240,7 @@ extern void iget_failed(struct inode *); | |||
2230 | extern void end_writeback(struct inode *); | 2240 | extern void end_writeback(struct inode *); |
2231 | extern void __destroy_inode(struct inode *); | 2241 | extern void __destroy_inode(struct inode *); |
2232 | extern struct inode *new_inode(struct super_block *); | 2242 | extern struct inode *new_inode(struct super_block *); |
2243 | extern void free_inode_nonrcu(struct inode *inode); | ||
2233 | extern int should_remove_suid(struct dentry *); | 2244 | extern int should_remove_suid(struct dentry *); |
2234 | extern int file_remove_suid(struct file *); | 2245 | extern int file_remove_suid(struct file *); |
2235 | 2246 | ||
@@ -2446,6 +2457,10 @@ static inline ino_t parent_ino(struct dentry *dentry) | |||
2446 | { | 2457 | { |
2447 | ino_t res; | 2458 | ino_t res; |
2448 | 2459 | ||
2460 | /* | ||
2461 | * Don't strictly need d_lock here? If the parent ino could change | ||
2462 | * then surely we'd have a deeper race in the caller? | ||
2463 | */ | ||
2449 | spin_lock(&dentry->d_lock); | 2464 | spin_lock(&dentry->d_lock); |
2450 | res = dentry->d_parent->d_inode->i_ino; | 2465 | res = dentry->d_parent->d_inode->i_ino; |
2451 | spin_unlock(&dentry->d_lock); | 2466 | spin_unlock(&dentry->d_lock); |