aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 15:51:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 15:51:21 -0400
commit052b398a43a7de8c68c13e7fa05d6b3d16ce6801 (patch)
tree8b7ee72d0617daf55083bc9cbc904ee22cb953db /fs/overlayfs
parentb953c0d234bc72e8489d3bf51a276c5c4ec85345 (diff)
parentb853a16176cf3e02c57e215743015614152c2428 (diff)
Merge branch 'for-linus-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "In this pile: pathname resolution rewrite. - recursion in link_path_walk() is gone. - nesting limits on symlinks are gone (the only limit remaining is that the total amount of symlinks is no more than 40, no matter how nested). - "fast" (inline) symlinks are handled without leaving rcuwalk mode. - stack footprint (independent of the nesting) is below kilobyte now, about on par with what it used to be with one level of nested symlinks and ~2.8 times lower than it used to be in the worst case. - struct nameidata is entirely private to fs/namei.c now (not even opaque pointers are being passed around). - ->follow_link() and ->put_link() calling conventions had been changed; all in-tree filesystems converted, out-of-tree should be able to follow reasonably easily. For out-of-tree conversions, see Documentation/filesystems/porting for details (and in-tree filesystems for examples of conversion). That has sat in -next since mid-May, seems to survive all testing without regressions and merges clean with v4.1" * 'for-linus-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (131 commits) turn user_{path_at,path,lpath,path_dir}() into static inlines namei: move saved_nd pointer into struct nameidata inline user_path_create() inline user_path_parent() namei: trim do_last() arguments namei: stash dfd and name into nameidata namei: fold path_cleanup() into terminate_walk() namei: saner calling conventions for filename_parentat() namei: saner calling conventions for filename_create() namei: shift nameidata down into filename_parentat() namei: make filename_lookup() reject ERR_PTR() passed as name namei: shift nameidata inside filename_lookup() namei: move putname() call into filename_lookup() namei: pass the struct path to store the result down into path_lookupat() namei: uninline set_root{,_rcu}() namei: be careful with mountpoint crossings in follow_dotdot_rcu() Documentation: remove outdated information from automount-support.txt get rid of assorted nameidata-related debris lustre: kill unused helper lustre: kill unused macro (LOOKUP_CONTINUE) ...
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/inode.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 04f124884687..308379b2d0b2 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -140,11 +140,12 @@ struct ovl_link_data {
140 void *cookie; 140 void *cookie;
141}; 141};
142 142
143static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd) 143static const char *ovl_follow_link(struct dentry *dentry, void **cookie)
144{ 144{
145 void *ret;
146 struct dentry *realdentry; 145 struct dentry *realdentry;
147 struct inode *realinode; 146 struct inode *realinode;
147 struct ovl_link_data *data = NULL;
148 const char *ret;
148 149
149 realdentry = ovl_dentry_real(dentry); 150 realdentry = ovl_dentry_real(dentry);
150 realinode = realdentry->d_inode; 151 realinode = realdentry->d_inode;
@@ -152,28 +153,28 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
152 if (WARN_ON(!realinode->i_op->follow_link)) 153 if (WARN_ON(!realinode->i_op->follow_link))
153 return ERR_PTR(-EPERM); 154 return ERR_PTR(-EPERM);
154 155
155 ret = realinode->i_op->follow_link(realdentry, nd);
156 if (IS_ERR(ret))
157 return ret;
158
159 if (realinode->i_op->put_link) { 156 if (realinode->i_op->put_link) {
160 struct ovl_link_data *data;
161
162 data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL); 157 data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
163 if (!data) { 158 if (!data)
164 realinode->i_op->put_link(realdentry, nd, ret);
165 return ERR_PTR(-ENOMEM); 159 return ERR_PTR(-ENOMEM);
166 }
167 data->realdentry = realdentry; 160 data->realdentry = realdentry;
168 data->cookie = ret; 161 }
169 162
170 return data; 163 ret = realinode->i_op->follow_link(realdentry, cookie);
171 } else { 164 if (IS_ERR_OR_NULL(ret)) {
172 return NULL; 165 kfree(data);
166 return ret;
173 } 167 }
168
169 if (data)
170 data->cookie = *cookie;
171
172 *cookie = data;
173
174 return ret;
174} 175}
175 176
176static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c) 177static void ovl_put_link(struct inode *unused, void *c)
177{ 178{
178 struct inode *realinode; 179 struct inode *realinode;
179 struct ovl_link_data *data = c; 180 struct ovl_link_data *data = c;
@@ -182,7 +183,7 @@ static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
182 return; 183 return;
183 184
184 realinode = data->realdentry->d_inode; 185 realinode = data->realdentry->d_inode;
185 realinode->i_op->put_link(data->realdentry, nd, data->cookie); 186 realinode->i_op->put_link(realinode, data->cookie);
186 kfree(data); 187 kfree(data);
187} 188}
188 189