summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-09-16 06:44:20 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-16 06:44:20 -0400
commitc568d68341be7030f5647def68851e469b21ca11 (patch)
treefe205e47e6d6d292557580c16ea0186a05752634
parentf3fbbb079263bd29ae592478de6808db7e708267 (diff)
locks: fix file locking on overlayfs
This patch allows flock, posix locks, ofd locks and leases to work correctly on overlayfs. Instead of using the underlying inode for storing lock context use the overlay inode. This allows locks to be persistent across copy-up. This is done by introducing locks_inode() helper and using it instead of file_inode() to get the inode in locking code. For non-overlayfs the two are equivalent, except for an extra pointer dereference in locks_inode(). Since lock operations are in "struct file_operations" we must also make sure not to call underlying filesystem's lock operations. Introcude a super block flag MS_NOREMOTELOCK to this effect. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Acked-by: Jeff Layton <jlayton@poochiereds.net> Cc: "J. Bruce Fields" <bfields@fieldses.org>
-rw-r--r--fs/locks.c50
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/open.c2
-rw-r--r--fs/overlayfs/super.c2
-rw-r--r--include/linux/fs.h16
-rw-r--r--include/uapi/linux/fs.h1
6 files changed, 46 insertions, 27 deletions
diff --git a/fs/locks.c b/fs/locks.c
index ee1b15f6fc13..c1656cff53ee 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -139,6 +139,11 @@
139#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) 139#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
140#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) 140#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
141 141
142static inline bool is_remote_lock(struct file *filp)
143{
144 return likely(!(filp->f_path.dentry->d_sb->s_flags & MS_NOREMOTELOCK));
145}
146
142static bool lease_breaking(struct file_lock *fl) 147static bool lease_breaking(struct file_lock *fl)
143{ 148{
144 return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING); 149 return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING);
@@ -791,7 +796,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
791{ 796{
792 struct file_lock *cfl; 797 struct file_lock *cfl;
793 struct file_lock_context *ctx; 798 struct file_lock_context *ctx;
794 struct inode *inode = file_inode(filp); 799 struct inode *inode = locks_inode(filp);
795 800
796 ctx = smp_load_acquire(&inode->i_flctx); 801 ctx = smp_load_acquire(&inode->i_flctx);
797 if (!ctx || list_empty_careful(&ctx->flc_posix)) { 802 if (!ctx || list_empty_careful(&ctx->flc_posix)) {
@@ -1192,7 +1197,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
1192int posix_lock_file(struct file *filp, struct file_lock *fl, 1197int posix_lock_file(struct file *filp, struct file_lock *fl,
1193 struct file_lock *conflock) 1198 struct file_lock *conflock)
1194{ 1199{
1195 return posix_lock_inode(file_inode(filp), fl, conflock); 1200 return posix_lock_inode(locks_inode(filp), fl, conflock);
1196} 1201}
1197EXPORT_SYMBOL(posix_lock_file); 1202EXPORT_SYMBOL(posix_lock_file);
1198 1203
@@ -1232,7 +1237,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1232int locks_mandatory_locked(struct file *file) 1237int locks_mandatory_locked(struct file *file)
1233{ 1238{
1234 int ret; 1239 int ret;
1235 struct inode *inode = file_inode(file); 1240 struct inode *inode = locks_inode(file);
1236 struct file_lock_context *ctx; 1241 struct file_lock_context *ctx;
1237 struct file_lock *fl; 1242 struct file_lock *fl;
1238 1243
@@ -1572,7 +1577,7 @@ EXPORT_SYMBOL(lease_get_mtime);
1572int fcntl_getlease(struct file *filp) 1577int fcntl_getlease(struct file *filp)
1573{ 1578{
1574 struct file_lock *fl; 1579 struct file_lock *fl;
1575 struct inode *inode = file_inode(filp); 1580 struct inode *inode = locks_inode(filp);
1576 struct file_lock_context *ctx; 1581 struct file_lock_context *ctx;
1577 int type = F_UNLCK; 1582 int type = F_UNLCK;
1578 LIST_HEAD(dispose); 1583 LIST_HEAD(dispose);
@@ -1580,7 +1585,7 @@ int fcntl_getlease(struct file *filp)
1580 ctx = smp_load_acquire(&inode->i_flctx); 1585 ctx = smp_load_acquire(&inode->i_flctx);
1581 if (ctx && !list_empty_careful(&ctx->flc_lease)) { 1586 if (ctx && !list_empty_careful(&ctx->flc_lease)) {
1582 spin_lock(&ctx->flc_lock); 1587 spin_lock(&ctx->flc_lock);
1583 time_out_leases(file_inode(filp), &dispose); 1588 time_out_leases(inode, &dispose);
1584 list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 1589 list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
1585 if (fl->fl_file != filp) 1590 if (fl->fl_file != filp)
1586 continue; 1591 continue;
@@ -1628,7 +1633,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
1628{ 1633{
1629 struct file_lock *fl, *my_fl = NULL, *lease; 1634 struct file_lock *fl, *my_fl = NULL, *lease;
1630 struct dentry *dentry = filp->f_path.dentry; 1635 struct dentry *dentry = filp->f_path.dentry;
1631 struct inode *inode = file_inode(filp); 1636 struct inode *inode = dentry->d_inode;
1632 struct file_lock_context *ctx; 1637 struct file_lock_context *ctx;
1633 bool is_deleg = (*flp)->fl_flags & FL_DELEG; 1638 bool is_deleg = (*flp)->fl_flags & FL_DELEG;
1634 int error; 1639 int error;
@@ -1742,7 +1747,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
1742{ 1747{
1743 int error = -EAGAIN; 1748 int error = -EAGAIN;
1744 struct file_lock *fl, *victim = NULL; 1749 struct file_lock *fl, *victim = NULL;
1745 struct inode *inode = file_inode(filp); 1750 struct inode *inode = locks_inode(filp);
1746 struct file_lock_context *ctx; 1751 struct file_lock_context *ctx;
1747 LIST_HEAD(dispose); 1752 LIST_HEAD(dispose);
1748 1753
@@ -1782,7 +1787,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
1782int generic_setlease(struct file *filp, long arg, struct file_lock **flp, 1787int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1783 void **priv) 1788 void **priv)
1784{ 1789{
1785 struct inode *inode = file_inode(filp); 1790 struct inode *inode = locks_inode(filp);
1786 int error; 1791 int error;
1787 1792
1788 if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE)) 1793 if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
@@ -1830,7 +1835,7 @@ EXPORT_SYMBOL(generic_setlease);
1830int 1835int
1831vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) 1836vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
1832{ 1837{
1833 if (filp->f_op->setlease) 1838 if (filp->f_op->setlease && is_remote_lock(filp))
1834 return filp->f_op->setlease(filp, arg, lease, priv); 1839 return filp->f_op->setlease(filp, arg, lease, priv);
1835 else 1840 else
1836 return generic_setlease(filp, arg, lease, priv); 1841 return generic_setlease(filp, arg, lease, priv);
@@ -1979,7 +1984,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1979 if (error) 1984 if (error)
1980 goto out_free; 1985 goto out_free;
1981 1986
1982 if (f.file->f_op->flock) 1987 if (f.file->f_op->flock && is_remote_lock(f.file))
1983 error = f.file->f_op->flock(f.file, 1988 error = f.file->f_op->flock(f.file,
1984 (can_sleep) ? F_SETLKW : F_SETLK, 1989 (can_sleep) ? F_SETLKW : F_SETLK,
1985 lock); 1990 lock);
@@ -2005,7 +2010,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
2005 */ 2010 */
2006int vfs_test_lock(struct file *filp, struct file_lock *fl) 2011int vfs_test_lock(struct file *filp, struct file_lock *fl)
2007{ 2012{
2008 if (filp->f_op->lock) 2013 if (filp->f_op->lock && is_remote_lock(filp))
2009 return filp->f_op->lock(filp, F_GETLK, fl); 2014 return filp->f_op->lock(filp, F_GETLK, fl);
2010 posix_test_lock(filp, fl); 2015 posix_test_lock(filp, fl);
2011 return 0; 2016 return 0;
@@ -2129,7 +2134,7 @@ out:
2129 */ 2134 */
2130int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 2135int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
2131{ 2136{
2132 if (filp->f_op->lock) 2137 if (filp->f_op->lock && is_remote_lock(filp))
2133 return filp->f_op->lock(filp, cmd, fl); 2138 return filp->f_op->lock(filp, cmd, fl);
2134 else 2139 else
2135 return posix_lock_file(filp, fl, conf); 2140 return posix_lock_file(filp, fl, conf);
@@ -2191,7 +2196,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
2191 if (file_lock == NULL) 2196 if (file_lock == NULL)
2192 return -ENOLCK; 2197 return -ENOLCK;
2193 2198
2194 inode = file_inode(filp); 2199 inode = locks_inode(filp);
2195 2200
2196 /* 2201 /*
2197 * This might block, so we do it before checking the inode. 2202 * This might block, so we do it before checking the inode.
@@ -2343,7 +2348,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2343 if (copy_from_user(&flock, l, sizeof(flock))) 2348 if (copy_from_user(&flock, l, sizeof(flock)))
2344 goto out; 2349 goto out;
2345 2350
2346 inode = file_inode(filp); 2351 inode = locks_inode(filp);
2347 2352
2348 /* Don't allow mandatory locks on files that may be memory mapped 2353 /* Don't allow mandatory locks on files that may be memory mapped
2349 * and shared. 2354 * and shared.
@@ -2426,6 +2431,7 @@ out:
2426void locks_remove_posix(struct file *filp, fl_owner_t owner) 2431void locks_remove_posix(struct file *filp, fl_owner_t owner)
2427{ 2432{
2428 int error; 2433 int error;
2434 struct inode *inode = locks_inode(filp);
2429 struct file_lock lock; 2435 struct file_lock lock;
2430 struct file_lock_context *ctx; 2436 struct file_lock_context *ctx;
2431 2437
@@ -2434,7 +2440,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
2434 * posix_lock_file(). Another process could be setting a lock on this 2440 * posix_lock_file(). Another process could be setting a lock on this
2435 * file at the same time, but we wouldn't remove that lock anyway. 2441 * file at the same time, but we wouldn't remove that lock anyway.
2436 */ 2442 */
2437 ctx = smp_load_acquire(&file_inode(filp)->i_flctx); 2443 ctx = smp_load_acquire(&inode->i_flctx);
2438 if (!ctx || list_empty(&ctx->flc_posix)) 2444 if (!ctx || list_empty(&ctx->flc_posix))
2439 return; 2445 return;
2440 2446
@@ -2452,7 +2458,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
2452 2458
2453 if (lock.fl_ops && lock.fl_ops->fl_release_private) 2459 if (lock.fl_ops && lock.fl_ops->fl_release_private)
2454 lock.fl_ops->fl_release_private(&lock); 2460 lock.fl_ops->fl_release_private(&lock);
2455 trace_locks_remove_posix(file_inode(filp), &lock, error); 2461 trace_locks_remove_posix(inode, &lock, error);
2456} 2462}
2457 2463
2458EXPORT_SYMBOL(locks_remove_posix); 2464EXPORT_SYMBOL(locks_remove_posix);
@@ -2469,12 +2475,12 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
2469 .fl_type = F_UNLCK, 2475 .fl_type = F_UNLCK,
2470 .fl_end = OFFSET_MAX, 2476 .fl_end = OFFSET_MAX,
2471 }; 2477 };
2472 struct inode *inode = file_inode(filp); 2478 struct inode *inode = locks_inode(filp);
2473 2479
2474 if (list_empty(&flctx->flc_flock)) 2480 if (list_empty(&flctx->flc_flock))
2475 return; 2481 return;
2476 2482
2477 if (filp->f_op->flock) 2483 if (filp->f_op->flock && is_remote_lock(filp))
2478 filp->f_op->flock(filp, F_SETLKW, &fl); 2484 filp->f_op->flock(filp, F_SETLKW, &fl);
2479 else 2485 else
2480 flock_lock_inode(inode, &fl); 2486 flock_lock_inode(inode, &fl);
@@ -2508,7 +2514,7 @@ void locks_remove_file(struct file *filp)
2508{ 2514{
2509 struct file_lock_context *ctx; 2515 struct file_lock_context *ctx;
2510 2516
2511 ctx = smp_load_acquire(&file_inode(filp)->i_flctx); 2517 ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
2512 if (!ctx) 2518 if (!ctx)
2513 return; 2519 return;
2514 2520
@@ -2552,7 +2558,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
2552 */ 2558 */
2553int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 2559int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
2554{ 2560{
2555 if (filp->f_op->lock) 2561 if (filp->f_op->lock && is_remote_lock(filp))
2556 return filp->f_op->lock(filp, F_CANCELLK, fl); 2562 return filp->f_op->lock(filp, F_CANCELLK, fl);
2557 return 0; 2563 return 0;
2558} 2564}
@@ -2580,7 +2586,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2580 fl_pid = fl->fl_pid; 2586 fl_pid = fl->fl_pid;
2581 2587
2582 if (fl->fl_file != NULL) 2588 if (fl->fl_file != NULL)
2583 inode = file_inode(fl->fl_file); 2589 inode = locks_inode(fl->fl_file);
2584 2590
2585 seq_printf(f, "%lld:%s ", id, pfx); 2591 seq_printf(f, "%lld:%s ", id, pfx);
2586 if (IS_POSIX(fl)) { 2592 if (IS_POSIX(fl)) {
@@ -2682,7 +2688,7 @@ static void __show_fd_locks(struct seq_file *f,
2682void show_fd_locks(struct seq_file *f, 2688void show_fd_locks(struct seq_file *f,
2683 struct file *filp, struct files_struct *files) 2689 struct file *filp, struct files_struct *files)
2684{ 2690{
2685 struct inode *inode = file_inode(filp); 2691 struct inode *inode = locks_inode(filp);
2686 struct file_lock_context *ctx; 2692 struct file_lock_context *ctx;
2687 int id = 0; 2693 int id = 0;
2688 2694
diff --git a/fs/namespace.c b/fs/namespace.c
index 7bb2cda3bfef..dcd9afe21e62 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2700,7 +2700,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2700 2700
2701 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | 2701 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
2702 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | 2702 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
2703 MS_STRICTATIME); 2703 MS_STRICTATIME | MS_NOREMOTELOCK);
2704 2704
2705 if (flags & MS_REMOUNT) 2705 if (flags & MS_REMOUNT)
2706 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, 2706 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
diff --git a/fs/open.c b/fs/open.c
index 4fd6e256f4f4..648fb9d3e97a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -726,7 +726,7 @@ static int do_dentry_open(struct file *f,
726 if (error) 726 if (error)
727 goto cleanup_all; 727 goto cleanup_all;
728 728
729 error = break_lease(inode, f->f_flags); 729 error = break_lease(locks_inode(f), f->f_flags);
730 if (error) 730 if (error)
731 goto cleanup_all; 731 goto cleanup_all;
732 732
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index e2a94a26767b..3d0b9dee2b76 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1320,7 +1320,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1320 sb->s_xattr = ovl_xattr_handlers; 1320 sb->s_xattr = ovl_xattr_handlers;
1321 sb->s_root = root_dentry; 1321 sb->s_root = root_dentry;
1322 sb->s_fs_info = ufs; 1322 sb->s_fs_info = ufs;
1323 sb->s_flags |= MS_POSIXACL; 1323 sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK;
1324 1324
1325 return 0; 1325 return 0;
1326 1326
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7db097d673a8..8ee0f011547f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1065,6 +1065,18 @@ struct file_lock_context {
1065 1065
1066extern void send_sigio(struct fown_struct *fown, int fd, int band); 1066extern void send_sigio(struct fown_struct *fown, int fd, int band);
1067 1067
1068/*
1069 * Return the inode to use for locking
1070 *
1071 * For overlayfs this should be the overlay inode, not the real inode returned
1072 * by file_inode(). For any other fs file_inode(filp) and locks_inode(filp) are
1073 * equal.
1074 */
1075static inline struct inode *locks_inode(const struct file *f)
1076{
1077 return f->f_path.dentry->d_inode;
1078}
1079
1068#ifdef CONFIG_FILE_LOCKING 1080#ifdef CONFIG_FILE_LOCKING
1069extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *); 1081extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *);
1070extern int fcntl_setlk(unsigned int, struct file *, unsigned int, 1082extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
@@ -1252,7 +1264,7 @@ static inline struct dentry *file_dentry(const struct file *file)
1252 1264
1253static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) 1265static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
1254{ 1266{
1255 return locks_lock_inode_wait(file_inode(filp), fl); 1267 return locks_lock_inode_wait(locks_inode(filp), fl);
1256} 1268}
1257 1269
1258struct fasync_struct { 1270struct fasync_struct {
@@ -2155,7 +2167,7 @@ static inline int mandatory_lock(struct inode *ino)
2155 2167
2156static inline int locks_verify_locked(struct file *file) 2168static inline int locks_verify_locked(struct file *file)
2157{ 2169{
2158 if (mandatory_lock(file_inode(file))) 2170 if (mandatory_lock(locks_inode(file)))
2159 return locks_mandatory_locked(file); 2171 return locks_mandatory_locked(file);
2160 return 0; 2172 return 0;
2161} 2173}
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3b00f7c8943f..2473272169f2 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -132,6 +132,7 @@ struct inodes_stat_t {
132#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ 132#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
133 133
134/* These sb flags are internal to the kernel */ 134/* These sb flags are internal to the kernel */
135#define MS_NOREMOTELOCK (1<<27)
135#define MS_NOSEC (1<<28) 136#define MS_NOSEC (1<<28)
136#define MS_BORN (1<<29) 137#define MS_BORN (1<<29)
137#define MS_ACTIVE (1<<30) 138#define MS_ACTIVE (1<<30)