diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-07-27 05:36:03 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-07-27 05:36:03 -0400 |
commit | 1b91dbdd2938a0102fea2d8853073159f2b08deb (patch) | |
tree | 6c1c54e4b15a1efbcd15a4d68d6366c71abf9979 /fs/overlayfs | |
parent | 523d939ef98fd712632d93a5a2b588e477a7565e (diff) | |
parent | 0cac643c102c0632dc2cc81e2490b0fec1cac0af (diff) |
Merge branch 'd_real' into overlayfs-next
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/inode.c | 31 | ||||
-rw-r--r-- | fs/overlayfs/overlayfs.h | 2 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 20 |
3 files changed, 25 insertions, 28 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index d1cdc60dd68f..d554e86abbe3 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -351,36 +351,25 @@ static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, | |||
351 | return true; | 351 | return true; |
352 | } | 352 | } |
353 | 353 | ||
354 | struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) | 354 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags) |
355 | { | 355 | { |
356 | int err; | 356 | int err = 0; |
357 | struct path realpath; | 357 | struct path realpath; |
358 | enum ovl_path_type type; | 358 | enum ovl_path_type type; |
359 | 359 | ||
360 | if (d_is_dir(dentry)) | ||
361 | return d_backing_inode(dentry); | ||
362 | |||
363 | type = ovl_path_real(dentry, &realpath); | 360 | type = ovl_path_real(dentry, &realpath); |
364 | if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { | 361 | if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { |
365 | err = ovl_want_write(dentry); | 362 | err = ovl_want_write(dentry); |
366 | if (err) | 363 | if (!err) { |
367 | return ERR_PTR(err); | 364 | if (file_flags & O_TRUNC) |
368 | 365 | err = ovl_copy_up_truncate(dentry); | |
369 | if (file_flags & O_TRUNC) | 366 | else |
370 | err = ovl_copy_up_truncate(dentry); | 367 | err = ovl_copy_up(dentry); |
371 | else | 368 | ovl_drop_write(dentry); |
372 | err = ovl_copy_up(dentry); | 369 | } |
373 | ovl_drop_write(dentry); | ||
374 | if (err) | ||
375 | return ERR_PTR(err); | ||
376 | |||
377 | ovl_path_upper(dentry, &realpath); | ||
378 | } | 370 | } |
379 | 371 | ||
380 | if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE) | 372 | return err; |
381 | return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags); | ||
382 | |||
383 | return d_backing_inode(realpath.dentry); | ||
384 | } | 373 | } |
385 | 374 | ||
386 | static const struct inode_operations ovl_file_inode_operations = { | 375 | static const struct inode_operations ovl_file_inode_operations = { |
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index cfbca53590d0..0d3f2ad45708 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h | |||
@@ -179,7 +179,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, | |||
179 | const char *name, void *value, size_t size); | 179 | const char *name, void *value, size_t size); |
180 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); | 180 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); |
181 | int ovl_removexattr(struct dentry *dentry, const char *name); | 181 | int ovl_removexattr(struct dentry *dentry, const char *name); |
182 | struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags); | 182 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); |
183 | 183 | ||
184 | struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, | 184 | struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, |
185 | struct ovl_entry *oe); | 185 | struct ovl_entry *oe); |
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 9a7693d5f8ff..5e254b3a8c56 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -304,7 +304,9 @@ static void ovl_dentry_release(struct dentry *dentry) | |||
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
307 | static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) | 307 | static struct dentry *ovl_d_real(struct dentry *dentry, |
308 | const struct inode *inode, | ||
309 | unsigned int open_flags) | ||
308 | { | 310 | { |
309 | struct dentry *real; | 311 | struct dentry *real; |
310 | 312 | ||
@@ -314,6 +316,16 @@ static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) | |||
314 | goto bug; | 316 | goto bug; |
315 | } | 317 | } |
316 | 318 | ||
319 | if (d_is_negative(dentry)) | ||
320 | return dentry; | ||
321 | |||
322 | if (open_flags) { | ||
323 | int err = ovl_open_maybe_copy_up(dentry, open_flags); | ||
324 | |||
325 | if (err) | ||
326 | return ERR_PTR(err); | ||
327 | } | ||
328 | |||
317 | real = ovl_dentry_upper(dentry); | 329 | real = ovl_dentry_upper(dentry); |
318 | if (real && (!inode || inode == d_inode(real))) | 330 | if (real && (!inode || inode == d_inode(real))) |
319 | return real; | 331 | return real; |
@@ -326,9 +338,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) | |||
326 | return real; | 338 | return real; |
327 | 339 | ||
328 | /* Handle recursion */ | 340 | /* Handle recursion */ |
329 | if (real->d_flags & DCACHE_OP_REAL) | 341 | return d_real(real, inode, open_flags); |
330 | return real->d_op->d_real(real, inode); | ||
331 | |||
332 | bug: | 342 | bug: |
333 | WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry, | 343 | WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry, |
334 | inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0); | 344 | inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0); |
@@ -378,13 +388,11 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) | |||
378 | 388 | ||
379 | static const struct dentry_operations ovl_dentry_operations = { | 389 | static const struct dentry_operations ovl_dentry_operations = { |
380 | .d_release = ovl_dentry_release, | 390 | .d_release = ovl_dentry_release, |
381 | .d_select_inode = ovl_d_select_inode, | ||
382 | .d_real = ovl_d_real, | 391 | .d_real = ovl_d_real, |
383 | }; | 392 | }; |
384 | 393 | ||
385 | static const struct dentry_operations ovl_reval_dentry_operations = { | 394 | static const struct dentry_operations ovl_reval_dentry_operations = { |
386 | .d_release = ovl_dentry_release, | 395 | .d_release = ovl_dentry_release, |
387 | .d_select_inode = ovl_d_select_inode, | ||
388 | .d_real = ovl_d_real, | 396 | .d_real = ovl_d_real, |
389 | .d_revalidate = ovl_dentry_revalidate, | 397 | .d_revalidate = ovl_dentry_revalidate, |
390 | .d_weak_revalidate = ovl_dentry_weak_revalidate, | 398 | .d_weak_revalidate = ovl_dentry_weak_revalidate, |