aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2018-10-01 04:07:05 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2018-10-01 04:07:05 -0400
commitab2257e9941b9ef28d4a4a451e4b146d40a21e18 (patch)
treef4c4b558fcec9846ea840ea721d494327c5192b4
parent261aaba72fdba17b74a3a434d9f925b43d90e958 (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.c13
-rw-r--r--fs/fuse/file.c8
-rw-r--r--fs/fuse/fuse_i.h62
-rw-r--r--fs/fuse/inode.c16
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
1620void fuse_init_dir(struct inode *inode) 1623void 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
1626void fuse_init_symlink(struct inode *inode) 1637void 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
3144void fuse_init_file_inode(struct inode *inode) 3144void 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)
124static void fuse_destroy_inode(struct inode *inode) 114static 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);