aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-07-27 05:36:03 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-07-27 05:36:03 -0400
commit1b91dbdd2938a0102fea2d8853073159f2b08deb (patch)
tree6c1c54e4b15a1efbcd15a4d68d6366c71abf9979
parent523d939ef98fd712632d93a5a2b588e477a7565e (diff)
parent0cac643c102c0632dc2cc81e2490b0fec1cac0af (diff)
Merge branch 'd_real' into overlayfs-next
-rw-r--r--Documentation/filesystems/Locking5
-rw-r--r--Documentation/filesystems/vfs.txt40
-rw-r--r--fs/dcache.c3
-rw-r--r--fs/namei.c2
-rw-r--r--fs/open.c8
-rw-r--r--fs/overlayfs/inode.c31
-rw-r--r--fs/overlayfs/overlayfs.h2
-rw-r--r--fs/overlayfs/super.c20
-rw-r--r--include/linux/dcache.h40
-rw-r--r--include/linux/fs.h7
10 files changed, 80 insertions, 78 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75eea7ce3d7c..d4def7b78a62 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -20,6 +20,8 @@ prototypes:
20 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); 20 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
21 struct vfsmount *(*d_automount)(struct path *path); 21 struct vfsmount *(*d_automount)(struct path *path);
22 int (*d_manage)(struct dentry *, bool); 22 int (*d_manage)(struct dentry *, bool);
23 struct dentry *(*d_real)(struct dentry *, const struct inode *,
24 unsigned int);
23 25
24locking rules: 26locking rules:
25 rename_lock ->d_lock may block rcu-walk 27 rename_lock ->d_lock may block rcu-walk
@@ -34,6 +36,7 @@ d_iput: no no yes no
34d_dname: no no no no 36d_dname: no no no no
35d_automount: no no yes no 37d_automount: no no yes no
36d_manage: no no yes (ref-walk) maybe 38d_manage: no no yes (ref-walk) maybe
39d_real no no yes no
37 40
38--------------------------- inode_operations --------------------------- 41--------------------------- inode_operations ---------------------------
39prototypes: 42prototypes:
@@ -66,7 +69,6 @@ prototypes:
66 struct file *, unsigned open_flag, 69 struct file *, unsigned open_flag,
67 umode_t create_mode, int *opened); 70 umode_t create_mode, int *opened);
68 int (*tmpfile) (struct inode *, struct dentry *, umode_t); 71 int (*tmpfile) (struct inode *, struct dentry *, umode_t);
69 int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
70 72
71locking rules: 73locking rules:
72 all may block 74 all may block
@@ -95,7 +97,6 @@ fiemap: no
95update_time: no 97update_time: no
96atomic_open: yes 98atomic_open: yes
97tmpfile: no 99tmpfile: no
98dentry_open: no
99 100
100 Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on 101 Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
101victim. 102victim.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index c61a223ef3ff..01c4f1741c20 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -364,7 +364,6 @@ struct inode_operations {
364 int (*atomic_open)(struct inode *, struct dentry *, struct file *, 364 int (*atomic_open)(struct inode *, struct dentry *, struct file *,
365 unsigned open_flag, umode_t create_mode, int *opened); 365 unsigned open_flag, umode_t create_mode, int *opened);
366 int (*tmpfile) (struct inode *, struct dentry *, umode_t); 366 int (*tmpfile) (struct inode *, struct dentry *, umode_t);
367 int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
368}; 367};
369 368
370Again, all methods are called without any locks being held, unless 369Again, all methods are called without any locks being held, unless
@@ -696,13 +695,6 @@ struct address_space_operations {
696 but instead uses bmap to find out where the blocks in the file 695 but instead uses bmap to find out where the blocks in the file
697 are and uses those addresses directly. 696 are and uses those addresses directly.
698 697
699 dentry_open: *WARNING: probably going away soon, do not use!* This is an
700 alternative to f_op->open(), the difference is that this method may open
701 a file not necessarily originating from the same filesystem as the one
702 i_op->open() was called on. It may be useful for stacking filesystems
703 which want to allow native I/O directly on underlying files.
704
705
706 invalidatepage: If a page has PagePrivate set, then invalidatepage 698 invalidatepage: If a page has PagePrivate set, then invalidatepage
707 will be called when part or all of the page is to be removed 699 will be called when part or all of the page is to be removed
708 from the address space. This generally corresponds to either a 700 from the address space. This generally corresponds to either a
@@ -938,6 +930,8 @@ struct dentry_operations {
938 char *(*d_dname)(struct dentry *, char *, int); 930 char *(*d_dname)(struct dentry *, char *, int);
939 struct vfsmount *(*d_automount)(struct path *); 931 struct vfsmount *(*d_automount)(struct path *);
940 int (*d_manage)(struct dentry *, bool); 932 int (*d_manage)(struct dentry *, bool);
933 struct dentry *(*d_real)(struct dentry *, const struct inode *,
934 unsigned int);
941}; 935};
942 936
943 d_revalidate: called when the VFS needs to revalidate a dentry. This 937 d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -1022,6 +1016,14 @@ struct dentry_operations {
1022 at the end of the buffer, and returns a pointer to the first char. 1016 at the end of the buffer, and returns a pointer to the first char.
1023 dynamic_dname() helper function is provided to take care of this. 1017 dynamic_dname() helper function is provided to take care of this.
1024 1018
1019 Example :
1020
1021 static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
1022 {
1023 return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
1024 dentry->d_inode->i_ino);
1025 }
1026
1025 d_automount: called when an automount dentry is to be traversed (optional). 1027 d_automount: called when an automount dentry is to be traversed (optional).
1026 This should create a new VFS mount record and return the record to the 1028 This should create a new VFS mount record and return the record to the
1027 caller. The caller is supplied with a path parameter giving the 1029 caller. The caller is supplied with a path parameter giving the
@@ -1060,13 +1062,23 @@ struct dentry_operations {
1060 This function is only used if DCACHE_MANAGE_TRANSIT is set on the 1062 This function is only used if DCACHE_MANAGE_TRANSIT is set on the
1061 dentry being transited from. 1063 dentry being transited from.
1062 1064
1063Example : 1065 d_real: overlay/union type filesystems implement this method to return one of
1066 the underlying dentries hidden by the overlay. It is used in three
1067 different modes:
1064 1068
1065static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) 1069 Called from open it may need to copy-up the file depending on the
1066{ 1070 supplied open flags. This mode is selected with a non-zero flags
1067 return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", 1071 argument. In this mode the d_real method can return an error.
1068 dentry->d_inode->i_ino); 1072
1069} 1073 Called from file_dentry() it returns the real dentry matching the inode
1074 argument. The real dentry may be from a lower layer already copied up,
1075 but still referenced from the file. This mode is selected with a
1076 non-NULL inode argument. This will always succeed.
1077
1078 With NULL inode and zero flags the topmost real underlying dentry is
1079 returned. This will always succeed.
1080
1081 This method is never called with both non-NULL inode and non-zero flags.
1070 1082
1071Each dentry has a pointer to its parent dentry, as well as a hash list 1083Each dentry has a pointer to its parent dentry, as well as a hash list
1072of child dentries. Child dentries are basically like files in a 1084of child dentries. Child dentries are basically like files in a
diff --git a/fs/dcache.c b/fs/dcache.c
index d6847d7b123d..5405b89fe8ec 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1729,7 +1729,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
1729 DCACHE_OP_REVALIDATE | 1729 DCACHE_OP_REVALIDATE |
1730 DCACHE_OP_WEAK_REVALIDATE | 1730 DCACHE_OP_WEAK_REVALIDATE |
1731 DCACHE_OP_DELETE | 1731 DCACHE_OP_DELETE |
1732 DCACHE_OP_SELECT_INODE |
1733 DCACHE_OP_REAL)); 1732 DCACHE_OP_REAL));
1734 dentry->d_op = op; 1733 dentry->d_op = op;
1735 if (!op) 1734 if (!op)
@@ -1746,8 +1745,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
1746 dentry->d_flags |= DCACHE_OP_DELETE; 1745 dentry->d_flags |= DCACHE_OP_DELETE;
1747 if (op->d_prune) 1746 if (op->d_prune)
1748 dentry->d_flags |= DCACHE_OP_PRUNE; 1747 dentry->d_flags |= DCACHE_OP_PRUNE;
1749 if (op->d_select_inode)
1750 dentry->d_flags |= DCACHE_OP_SELECT_INODE;
1751 if (op->d_real) 1748 if (op->d_real)
1752 dentry->d_flags |= DCACHE_OP_REAL; 1749 dentry->d_flags |= DCACHE_OP_REAL;
1753 1750
diff --git a/fs/namei.c b/fs/namei.c
index 70580ab1445c..bb7a2e0b959c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4328,7 +4328,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
4328 * Check source == target. 4328 * Check source == target.
4329 * On overlayfs need to look at underlying inodes. 4329 * On overlayfs need to look at underlying inodes.
4330 */ 4330 */
4331 if (vfs_select_inode(old_dentry, 0) == vfs_select_inode(new_dentry, 0)) 4331 if (d_real_inode(old_dentry) == d_real_inode(new_dentry))
4332 return 0; 4332 return 0;
4333 4333
4334 error = may_delete(old_dir, old_dentry, is_dir); 4334 error = may_delete(old_dir, old_dentry, is_dir);
diff --git a/fs/open.c b/fs/open.c
index 93ae3cdee4ab..bf66cf1a9f5c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -840,13 +840,13 @@ EXPORT_SYMBOL(file_path);
840int vfs_open(const struct path *path, struct file *file, 840int vfs_open(const struct path *path, struct file *file,
841 const struct cred *cred) 841 const struct cred *cred)
842{ 842{
843 struct inode *inode = vfs_select_inode(path->dentry, file->f_flags); 843 struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags);
844 844
845 if (IS_ERR(inode)) 845 if (IS_ERR(dentry))
846 return PTR_ERR(inode); 846 return PTR_ERR(dentry);
847 847
848 file->f_path = *path; 848 file->f_path = *path;
849 return do_dentry_open(file, inode, NULL, cred); 849 return do_dentry_open(file, d_backing_inode(dentry), NULL, cred);
850} 850}
851 851
852struct file *dentry_open(const struct path *path, int flags, 852struct file *dentry_open(const struct path *path, int flags,
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
354struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) 354int 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
386static const struct inode_operations ovl_file_inode_operations = { 375static 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);
180ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); 180ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
181int ovl_removexattr(struct dentry *dentry, const char *name); 181int ovl_removexattr(struct dentry *dentry, const char *name);
182struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags); 182int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
183 183
184struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, 184struct 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
307static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) 307static 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
332bug: 342bug:
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
379static const struct dentry_operations ovl_dentry_operations = { 389static 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
385static const struct dentry_operations ovl_reval_dentry_operations = { 394static 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,
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index f53fa055021a..14df83609c7f 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -139,8 +139,8 @@ struct dentry_operations {
139 char *(*d_dname)(struct dentry *, char *, int); 139 char *(*d_dname)(struct dentry *, char *, int);
140 struct vfsmount *(*d_automount)(struct path *); 140 struct vfsmount *(*d_automount)(struct path *);
141 int (*d_manage)(struct dentry *, bool); 141 int (*d_manage)(struct dentry *, bool);
142 struct inode *(*d_select_inode)(struct dentry *, unsigned); 142 struct dentry *(*d_real)(struct dentry *, const struct inode *,
143 struct dentry *(*d_real)(struct dentry *, struct inode *); 143 unsigned int);
144} ____cacheline_aligned; 144} ____cacheline_aligned;
145 145
146/* 146/*
@@ -206,10 +206,8 @@ struct dentry_operations {
206 206
207#define DCACHE_MAY_FREE 0x00800000 207#define DCACHE_MAY_FREE 0x00800000
208#define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ 208#define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */
209#define DCACHE_OP_SELECT_INODE 0x02000000 /* Unioned entry: dcache op selects inode */ 209#define DCACHE_ENCRYPTED_WITH_KEY 0x02000000 /* dir is encrypted with a valid key */
210 210#define DCACHE_OP_REAL 0x04000000
211#define DCACHE_ENCRYPTED_WITH_KEY 0x04000000 /* dir is encrypted with a valid key */
212#define DCACHE_OP_REAL 0x08000000
213 211
214#define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */ 212#define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */
215#define DCACHE_DENTRY_CURSOR 0x20000000 213#define DCACHE_DENTRY_CURSOR 0x20000000
@@ -557,25 +555,27 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
557 return upper; 555 return upper;
558} 556}
559 557
560static inline struct dentry *d_real(struct dentry *dentry) 558/**
559 * d_real - Return the real dentry
560 * @dentry: the dentry to query
561 * @inode: inode to select the dentry from multiple layers (can be NULL)
562 * @flags: open flags to control copy-up behavior
563 *
564 * If dentry is on an union/overlay, then return the underlying, real dentry.
565 * Otherwise return the dentry itself.
566 *
567 * See also: Documentation/filesystems/vfs.txt
568 */
569static inline struct dentry *d_real(struct dentry *dentry,
570 const struct inode *inode,
571 unsigned int flags)
561{ 572{
562 if (unlikely(dentry->d_flags & DCACHE_OP_REAL)) 573 if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
563 return dentry->d_op->d_real(dentry, NULL); 574 return dentry->d_op->d_real(dentry, inode, flags);
564 else 575 else
565 return dentry; 576 return dentry;
566} 577}
567 578
568static inline struct inode *vfs_select_inode(struct dentry *dentry,
569 unsigned open_flags)
570{
571 struct inode *inode = d_inode(dentry);
572
573 if (inode && unlikely(dentry->d_flags & DCACHE_OP_SELECT_INODE))
574 inode = dentry->d_op->d_select_inode(dentry, open_flags);
575
576 return inode;
577}
578
579/** 579/**
580 * d_real_inode - Return the real inode 580 * d_real_inode - Return the real inode
581 * @dentry: The dentry to query 581 * @dentry: The dentry to query
@@ -585,7 +585,7 @@ static inline struct inode *vfs_select_inode(struct dentry *dentry,
585 */ 585 */
586static inline struct inode *d_real_inode(struct dentry *dentry) 586static inline struct inode *d_real_inode(struct dentry *dentry)
587{ 587{
588 return d_backing_inode(d_real(dentry)); 588 return d_backing_inode(d_real(dentry, NULL, 0));
589} 589}
590 590
591 591
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd288148a6b1..bacc0733663c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1272,12 +1272,7 @@ static inline struct inode *file_inode(const struct file *f)
1272 1272
1273static inline struct dentry *file_dentry(const struct file *file) 1273static inline struct dentry *file_dentry(const struct file *file)
1274{ 1274{
1275 struct dentry *dentry = file->f_path.dentry; 1275 return d_real(file->f_path.dentry, file_inode(file), 0);
1276
1277 if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
1278 return dentry->d_op->d_real(dentry, file_inode(file));
1279 else
1280 return dentry;
1281} 1276}
1282 1277
1283static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) 1278static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)