diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2018-10-01 04:07:05 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2018-10-01 04:07:05 -0400 |
commit | ab2257e9941b9ef28d4a4a451e4b146d40a21e18 (patch) | |
tree | f4c4b558fcec9846ea840ea721d494327c5192b4 | |
parent | 261aaba72fdba17b74a3a434d9f925b43d90e958 (diff) |
fuse: reduce size of struct fuse_inode
Do this by grouping fields used for cached writes and putting them into a
union with fileds used for cached readdir (with obviously no overlap, since
we don't have hybrid objects).
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r-- | fs/fuse/dir.c | 13 | ||||
-rw-r--r-- | fs/fuse/file.c | 8 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 62 | ||||
-rw-r--r-- | fs/fuse/inode.c | 16 |
4 files changed, 58 insertions, 41 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 6800fdc3e730..d1b2f42d746e 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1414,8 +1414,11 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, | |||
1414 | file = NULL; | 1414 | file = NULL; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | if (attr->ia_valid & ATTR_SIZE) | 1417 | if (attr->ia_valid & ATTR_SIZE) { |
1418 | if (WARN_ON(!S_ISREG(inode->i_mode))) | ||
1419 | return -EIO; | ||
1418 | is_truncate = true; | 1420 | is_truncate = true; |
1421 | } | ||
1419 | 1422 | ||
1420 | if (is_truncate) { | 1423 | if (is_truncate) { |
1421 | fuse_set_nowrite(inode); | 1424 | fuse_set_nowrite(inode); |
@@ -1619,8 +1622,16 @@ void fuse_init_common(struct inode *inode) | |||
1619 | 1622 | ||
1620 | void fuse_init_dir(struct inode *inode) | 1623 | void fuse_init_dir(struct inode *inode) |
1621 | { | 1624 | { |
1625 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1626 | |||
1622 | inode->i_op = &fuse_dir_inode_operations; | 1627 | inode->i_op = &fuse_dir_inode_operations; |
1623 | inode->i_fop = &fuse_dir_operations; | 1628 | inode->i_fop = &fuse_dir_operations; |
1629 | |||
1630 | spin_lock_init(&fi->rdc.lock); | ||
1631 | fi->rdc.cached = false; | ||
1632 | fi->rdc.size = 0; | ||
1633 | fi->rdc.pos = 0; | ||
1634 | fi->rdc.version = 0; | ||
1624 | } | 1635 | } |
1625 | 1636 | ||
1626 | void fuse_init_symlink(struct inode *inode) | 1637 | void fuse_init_symlink(struct inode *inode) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e10c0443c56f..b10d14baeb1f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -3143,6 +3143,14 @@ static const struct address_space_operations fuse_file_aops = { | |||
3143 | 3143 | ||
3144 | void fuse_init_file_inode(struct inode *inode) | 3144 | void fuse_init_file_inode(struct inode *inode) |
3145 | { | 3145 | { |
3146 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
3147 | |||
3146 | inode->i_fop = &fuse_file_operations; | 3148 | inode->i_fop = &fuse_file_operations; |
3147 | inode->i_data.a_ops = &fuse_file_aops; | 3149 | inode->i_data.a_ops = &fuse_file_aops; |
3150 | |||
3151 | INIT_LIST_HEAD(&fi->write_files); | ||
3152 | INIT_LIST_HEAD(&fi->queued_writes); | ||
3153 | fi->writectr = 0; | ||
3154 | init_waitqueue_head(&fi->page_waitq); | ||
3155 | INIT_LIST_HEAD(&fi->writepages); | ||
3148 | } | 3156 | } |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d9d1ea78efa6..f5bdce84e766 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -87,45 +87,51 @@ struct fuse_inode { | |||
87 | /** Version of last attribute change */ | 87 | /** Version of last attribute change */ |
88 | u64 attr_version; | 88 | u64 attr_version; |
89 | 89 | ||
90 | /** Files usable in writepage. Protected by fc->lock */ | 90 | union { |
91 | struct list_head write_files; | 91 | /* Write related fields (regular file only) */ |
92 | struct { | ||
93 | /* Files usable in writepage. Protected by fc->lock */ | ||
94 | struct list_head write_files; | ||
92 | 95 | ||
93 | /** Writepages pending on truncate or fsync */ | 96 | /* Writepages pending on truncate or fsync */ |
94 | struct list_head queued_writes; | 97 | struct list_head queued_writes; |
95 | 98 | ||
96 | /** Number of sent writes, a negative bias (FUSE_NOWRITE) | 99 | /* Number of sent writes, a negative bias |
97 | * means more writes are blocked */ | 100 | * (FUSE_NOWRITE) means more writes are blocked */ |
98 | int writectr; | 101 | int writectr; |
99 | 102 | ||
100 | /** Waitq for writepage completion */ | 103 | /* Waitq for writepage completion */ |
101 | wait_queue_head_t page_waitq; | 104 | wait_queue_head_t page_waitq; |
102 | 105 | ||
103 | /** List of writepage requestst (pending or sent) */ | 106 | /* List of writepage requestst (pending or sent) */ |
104 | struct list_head writepages; | 107 | struct list_head writepages; |
108 | }; | ||
105 | 109 | ||
106 | /* readdir cache */ | 110 | /* readdir cache (directory only) */ |
107 | struct { | 111 | struct { |
108 | /* true if fully cached */ | 112 | /* true if fully cached */ |
109 | bool cached; | 113 | bool cached; |
110 | 114 | ||
111 | /* size of cache */ | 115 | /* size of cache */ |
112 | loff_t size; | 116 | loff_t size; |
113 | 117 | ||
114 | /* position at end of cache (position of next entry) */ | 118 | /* position at end of cache (position of next entry) */ |
115 | loff_t pos; | 119 | loff_t pos; |
116 | 120 | ||
117 | /* version of the cache */ | 121 | /* version of the cache */ |
118 | u64 version; | 122 | u64 version; |
119 | 123 | ||
120 | /* modification time of directory when cache was started */ | 124 | /* modification time of directory when cache was |
121 | struct timespec64 mtime; | 125 | * started */ |
126 | struct timespec64 mtime; | ||
122 | 127 | ||
123 | /* iversion of directory when cache was started */ | 128 | /* iversion of directory when cache was started */ |
124 | u64 iversion; | 129 | u64 iversion; |
125 | 130 | ||
126 | /* protects above fields */ | 131 | /* protects above fields */ |
127 | spinlock_t lock; | 132 | spinlock_t lock; |
128 | } rdc; | 133 | } rdc; |
134 | }; | ||
129 | 135 | ||
130 | /** Miscellaneous bits describing inode state */ | 136 | /** Miscellaneous bits describing inode state */ |
131 | unsigned long state; | 137 | unsigned long state; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index eef2ae713f75..82db1ab53420 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -93,18 +93,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
93 | fi->nodeid = 0; | 93 | fi->nodeid = 0; |
94 | fi->nlookup = 0; | 94 | fi->nlookup = 0; |
95 | fi->attr_version = 0; | 95 | fi->attr_version = 0; |
96 | fi->writectr = 0; | ||
97 | fi->orig_ino = 0; | 96 | fi->orig_ino = 0; |
98 | fi->state = 0; | 97 | fi->state = 0; |
99 | INIT_LIST_HEAD(&fi->write_files); | ||
100 | INIT_LIST_HEAD(&fi->queued_writes); | ||
101 | INIT_LIST_HEAD(&fi->writepages); | ||
102 | init_waitqueue_head(&fi->page_waitq); | ||
103 | spin_lock_init(&fi->rdc.lock); | ||
104 | fi->rdc.cached = false; | ||
105 | fi->rdc.size = 0; | ||
106 | fi->rdc.pos = 0; | ||
107 | fi->rdc.version = 0; | ||
108 | mutex_init(&fi->mutex); | 98 | mutex_init(&fi->mutex); |
109 | fi->forget = fuse_alloc_forget(); | 99 | fi->forget = fuse_alloc_forget(); |
110 | if (!fi->forget) { | 100 | if (!fi->forget) { |
@@ -124,8 +114,10 @@ static void fuse_i_callback(struct rcu_head *head) | |||
124 | static void fuse_destroy_inode(struct inode *inode) | 114 | static void fuse_destroy_inode(struct inode *inode) |
125 | { | 115 | { |
126 | struct fuse_inode *fi = get_fuse_inode(inode); | 116 | struct fuse_inode *fi = get_fuse_inode(inode); |
127 | BUG_ON(!list_empty(&fi->write_files)); | 117 | if (S_ISREG(inode->i_mode)) { |
128 | BUG_ON(!list_empty(&fi->queued_writes)); | 118 | WARN_ON(!list_empty(&fi->write_files)); |
119 | WARN_ON(!list_empty(&fi->queued_writes)); | ||
120 | } | ||
129 | mutex_destroy(&fi->mutex); | 121 | mutex_destroy(&fi->mutex); |
130 | kfree(fi->forget); | 122 | kfree(fi->forget); |
131 | call_rcu(&inode->i_rcu, fuse_i_callback); | 123 | call_rcu(&inode->i_rcu, fuse_i_callback); |