All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org,
	hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
	cluster-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 09/10] locks: move freeing of leases outside of i_lock
Date: Sat, 23 Aug 2014 10:41:17 -0400	[thread overview]
Message-ID: <1408804878-1331-10-git-send-email-jlayton@primarydata.com> (raw)
In-Reply-To: <1408804878-1331-1-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>

There was only one place where we still could free a file_lock while
holding the i_lock -- lease_modify. Add a new list_head argument to the
lm_change operation, pass in a private list when calling it, and fix
those callers to dispose of the list once the lock has been dropped.

Signed-off-by: Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
---
 fs/locks.c          | 35 ++++++++++++++++++++++-------------
 fs/nfsd/nfs4state.c |  6 +++---
 include/linux/fs.h  |  7 ++++---
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 49210d5cbf41..98907cecaa44 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1297,7 +1297,7 @@ static void lease_clear_pending(struct file_lock *fl, int arg)
 }
 
 /* We already had a lease on this file; just change its type */
-int lease_modify(struct file_lock **before, int arg)
+int lease_modify(struct file_lock **before, int arg, struct list_head *dispose)
 {
 	struct file_lock *fl = *before;
 	int error = assign_type(fl, arg);
@@ -1316,7 +1316,7 @@ int lease_modify(struct file_lock **before, int arg)
 			printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
 			fl->fl_fasync = NULL;
 		}
-		locks_delete_lock(before, NULL);
+		locks_delete_lock(before, dispose);
 	}
 	return 0;
 }
@@ -1330,7 +1330,7 @@ static bool past_time(unsigned long then)
 	return time_after(jiffies, then);
 }
 
-static void time_out_leases(struct inode *inode)
+static void time_out_leases(struct inode *inode, struct list_head *dispose)
 {
 	struct file_lock **before;
 	struct file_lock *fl;
@@ -1341,9 +1341,9 @@ static void time_out_leases(struct inode *inode)
 	while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
 		trace_time_out_leases(inode, fl);
 		if (past_time(fl->fl_downgrade_time))
-			lease_modify(before, F_RDLCK);
+			lease_modify(before, F_RDLCK, dispose);
 		if (past_time(fl->fl_break_time))
-			lease_modify(before, F_UNLCK);
+			lease_modify(before, F_UNLCK, dispose);
 		if (fl == *before)	/* lease_modify may have freed fl */
 			before = &fl->fl_next;
 	}
@@ -1378,6 +1378,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 	int i_have_this_lease = 0;
 	bool lease_conflict = false;
 	int want_write = (mode & O_ACCMODE) != O_RDONLY;
+	LIST_HEAD(dispose);
 
 	new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
 	if (IS_ERR(new_fl))
@@ -1386,7 +1387,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 
 	spin_lock(&inode->i_lock);
 
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	flock = inode->i_flock;
 	if ((flock == NULL) || !IS_LEASE(flock))
@@ -1441,6 +1442,7 @@ restart:
 	locks_insert_block(flock, new_fl);
 	trace_break_lease_block(inode, new_fl);
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	error = wait_event_interruptible_timeout(new_fl->fl_wait,
 						!new_fl->fl_next, break_time);
 	spin_lock(&inode->i_lock);
@@ -1448,7 +1450,7 @@ restart:
 	locks_delete_block(new_fl);
 	if (error >= 0) {
 		if (error == 0)
-			time_out_leases(inode);
+			time_out_leases(inode, &dispose);
 		/*
 		 * Wait for the next conflicting lease that has not been
 		 * broken yet
@@ -1463,6 +1465,7 @@ restart:
 
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	locks_free_lock(new_fl);
 	return error;
 }
@@ -1527,9 +1530,10 @@ int fcntl_getlease(struct file *filp)
 	struct file_lock *fl;
 	struct inode *inode = file_inode(filp);
 	int type = F_UNLCK;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(file_inode(filp));
+	time_out_leases(file_inode(filp), &dispose);
 	for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl);
 			fl = fl->fl_next) {
 		if (fl->fl_file == filp) {
@@ -1538,6 +1542,7 @@ int fcntl_getlease(struct file *filp)
 		}
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return type;
 }
 
@@ -1575,6 +1580,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	struct inode *inode = dentry->d_inode;
 	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
 	int error;
+	LIST_HEAD(dispose);
 
 	lease = *flp;
 	trace_generic_add_lease(inode, lease);
@@ -1598,7 +1604,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	}
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	error = check_conflicting_open(dentry, arg);
 	if (error)
@@ -1636,7 +1642,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 
 	if (my_before != NULL) {
 		lease = *my_before;
-		error = lease->fl_lmops->lm_change(my_before, arg);
+		error = lease->fl_lmops->lm_change(my_before, arg, &dispose);
 		if (error)
 			goto out;
 		goto out_setup;
@@ -1666,6 +1672,7 @@ out_setup:
 		lease->fl_lmops->lm_setup(lease, aux);
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	if (is_deleg)
 		mutex_unlock(&inode->i_mutex);
 	if (!error && !my_before)
@@ -1682,17 +1689,19 @@ static int generic_delete_lease(struct file *filp)
 	struct file_lock *fl, **before;
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 	for (before = &inode->i_flock;
 			((fl = *before) != NULL) && IS_LEASE(fl);
 			before = &fl->fl_next) {
 		if (fl->fl_file != filp)
 			continue;
-		error = fl->fl_lmops->lm_change(before, F_UNLCK);
+		error = fl->fl_lmops->lm_change(before, F_UNLCK, &dispose);
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return error;
 }
 
@@ -2388,7 +2397,7 @@ void locks_remove_file(struct file *filp)
 	while ((fl = *before) != NULL) {
 		if (fl->fl_file == filp) {
 			if (IS_LEASE(fl)) {
-				lease_modify(before, F_UNLCK);
+				lease_modify(before, F_UNLCK, &dispose);
 				continue;
 			}
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6af5d0890373..623576301e38 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3423,11 +3423,11 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
 	spin_unlock(&fp->fi_lock);
 }
 
-static
-int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
+static int
+nfsd_change_deleg_cb(struct file_lock **onlist, int arg, struct list_head *dispose)
 {
 	if (arg & F_UNLCK)
-		return lease_modify(onlist, arg);
+		return lease_modify(onlist, arg, dispose);
 	else
 		return -EAGAIN;
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 70d22c12924f..e3dbcf269cd2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -873,7 +873,7 @@ struct lock_manager_operations {
 	void (*lm_notify)(struct file_lock *);	/* unblock callback */
 	int (*lm_grant)(struct file_lock *, int);
 	void (*lm_break)(struct file_lock *);
-	int (*lm_change)(struct file_lock **, int);
+	int (*lm_change)(struct file_lock **, int, struct list_head *);
 	void (*lm_setup)(struct file_lock *, void **);
 };
 
@@ -985,7 +985,7 @@ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int t
 extern void lease_get_mtime(struct inode *, struct timespec *time);
 extern int generic_setlease(struct file *, long, struct file_lock **, void **aux);
 extern int vfs_setlease(struct file *, long, struct file_lock **, void **aux);
-extern int lease_modify(struct file_lock **, int);
+extern int lease_modify(struct file_lock **, int, struct list_head *);
 #else /* !CONFIG_FILE_LOCKING */
 static inline int fcntl_getlk(struct file *file, unsigned int cmd,
 			      struct flock __user *user)
@@ -1112,7 +1112,8 @@ static inline int vfs_setlease(struct file *filp, long arg,
 	return -EINVAL;
 }
 
-static inline int lease_modify(struct file_lock **before, int arg)
+static inline int lease_modify(struct file_lock **before, int arg,
+			       struct list_head *dispose)
 {
 	return -EINVAL;
 }
-- 
1.9.3

WARNING: multiple messages have this Message-ID (diff)
From: Jeff Layton <jlayton@primarydata.com>
To: linux-fsdevel@vger.kernel.org
Cc: bfields@fieldses.org, hch@infradead.org,
	cluster-devel@redhat.com, linux-cifs@vger.kernel.org,
	linux-nfs@vger.kernel.org
Subject: [PATCH 09/10] locks: move freeing of leases outside of i_lock
Date: Sat, 23 Aug 2014 10:41:17 -0400	[thread overview]
Message-ID: <1408804878-1331-10-git-send-email-jlayton@primarydata.com> (raw)
In-Reply-To: <1408804878-1331-1-git-send-email-jlayton@primarydata.com>

There was only one place where we still could free a file_lock while
holding the i_lock -- lease_modify. Add a new list_head argument to the
lm_change operation, pass in a private list when calling it, and fix
those callers to dispose of the list once the lock has been dropped.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 fs/locks.c          | 35 ++++++++++++++++++++++-------------
 fs/nfsd/nfs4state.c |  6 +++---
 include/linux/fs.h  |  7 ++++---
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 49210d5cbf41..98907cecaa44 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1297,7 +1297,7 @@ static void lease_clear_pending(struct file_lock *fl, int arg)
 }
 
 /* We already had a lease on this file; just change its type */
-int lease_modify(struct file_lock **before, int arg)
+int lease_modify(struct file_lock **before, int arg, struct list_head *dispose)
 {
 	struct file_lock *fl = *before;
 	int error = assign_type(fl, arg);
@@ -1316,7 +1316,7 @@ int lease_modify(struct file_lock **before, int arg)
 			printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
 			fl->fl_fasync = NULL;
 		}
-		locks_delete_lock(before, NULL);
+		locks_delete_lock(before, dispose);
 	}
 	return 0;
 }
@@ -1330,7 +1330,7 @@ static bool past_time(unsigned long then)
 	return time_after(jiffies, then);
 }
 
-static void time_out_leases(struct inode *inode)
+static void time_out_leases(struct inode *inode, struct list_head *dispose)
 {
 	struct file_lock **before;
 	struct file_lock *fl;
@@ -1341,9 +1341,9 @@ static void time_out_leases(struct inode *inode)
 	while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
 		trace_time_out_leases(inode, fl);
 		if (past_time(fl->fl_downgrade_time))
-			lease_modify(before, F_RDLCK);
+			lease_modify(before, F_RDLCK, dispose);
 		if (past_time(fl->fl_break_time))
-			lease_modify(before, F_UNLCK);
+			lease_modify(before, F_UNLCK, dispose);
 		if (fl == *before)	/* lease_modify may have freed fl */
 			before = &fl->fl_next;
 	}
@@ -1378,6 +1378,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 	int i_have_this_lease = 0;
 	bool lease_conflict = false;
 	int want_write = (mode & O_ACCMODE) != O_RDONLY;
+	LIST_HEAD(dispose);
 
 	new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
 	if (IS_ERR(new_fl))
@@ -1386,7 +1387,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 
 	spin_lock(&inode->i_lock);
 
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	flock = inode->i_flock;
 	if ((flock == NULL) || !IS_LEASE(flock))
@@ -1441,6 +1442,7 @@ restart:
 	locks_insert_block(flock, new_fl);
 	trace_break_lease_block(inode, new_fl);
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	error = wait_event_interruptible_timeout(new_fl->fl_wait,
 						!new_fl->fl_next, break_time);
 	spin_lock(&inode->i_lock);
@@ -1448,7 +1450,7 @@ restart:
 	locks_delete_block(new_fl);
 	if (error >= 0) {
 		if (error == 0)
-			time_out_leases(inode);
+			time_out_leases(inode, &dispose);
 		/*
 		 * Wait for the next conflicting lease that has not been
 		 * broken yet
@@ -1463,6 +1465,7 @@ restart:
 
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	locks_free_lock(new_fl);
 	return error;
 }
@@ -1527,9 +1530,10 @@ int fcntl_getlease(struct file *filp)
 	struct file_lock *fl;
 	struct inode *inode = file_inode(filp);
 	int type = F_UNLCK;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(file_inode(filp));
+	time_out_leases(file_inode(filp), &dispose);
 	for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl);
 			fl = fl->fl_next) {
 		if (fl->fl_file == filp) {
@@ -1538,6 +1542,7 @@ int fcntl_getlease(struct file *filp)
 		}
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return type;
 }
 
@@ -1575,6 +1580,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	struct inode *inode = dentry->d_inode;
 	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
 	int error;
+	LIST_HEAD(dispose);
 
 	lease = *flp;
 	trace_generic_add_lease(inode, lease);
@@ -1598,7 +1604,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	}
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	error = check_conflicting_open(dentry, arg);
 	if (error)
@@ -1636,7 +1642,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 
 	if (my_before != NULL) {
 		lease = *my_before;
-		error = lease->fl_lmops->lm_change(my_before, arg);
+		error = lease->fl_lmops->lm_change(my_before, arg, &dispose);
 		if (error)
 			goto out;
 		goto out_setup;
@@ -1666,6 +1672,7 @@ out_setup:
 		lease->fl_lmops->lm_setup(lease, aux);
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	if (is_deleg)
 		mutex_unlock(&inode->i_mutex);
 	if (!error && !my_before)
@@ -1682,17 +1689,19 @@ static int generic_delete_lease(struct file *filp)
 	struct file_lock *fl, **before;
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 	for (before = &inode->i_flock;
 			((fl = *before) != NULL) && IS_LEASE(fl);
 			before = &fl->fl_next) {
 		if (fl->fl_file != filp)
 			continue;
-		error = fl->fl_lmops->lm_change(before, F_UNLCK);
+		error = fl->fl_lmops->lm_change(before, F_UNLCK, &dispose);
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return error;
 }
 
@@ -2388,7 +2397,7 @@ void locks_remove_file(struct file *filp)
 	while ((fl = *before) != NULL) {
 		if (fl->fl_file == filp) {
 			if (IS_LEASE(fl)) {
-				lease_modify(before, F_UNLCK);
+				lease_modify(before, F_UNLCK, &dispose);
 				continue;
 			}
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6af5d0890373..623576301e38 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3423,11 +3423,11 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
 	spin_unlock(&fp->fi_lock);
 }
 
-static
-int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
+static int
+nfsd_change_deleg_cb(struct file_lock **onlist, int arg, struct list_head *dispose)
 {
 	if (arg & F_UNLCK)
-		return lease_modify(onlist, arg);
+		return lease_modify(onlist, arg, dispose);
 	else
 		return -EAGAIN;
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 70d22c12924f..e3dbcf269cd2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -873,7 +873,7 @@ struct lock_manager_operations {
 	void (*lm_notify)(struct file_lock *);	/* unblock callback */
 	int (*lm_grant)(struct file_lock *, int);
 	void (*lm_break)(struct file_lock *);
-	int (*lm_change)(struct file_lock **, int);
+	int (*lm_change)(struct file_lock **, int, struct list_head *);
 	void (*lm_setup)(struct file_lock *, void **);
 };
 
@@ -985,7 +985,7 @@ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int t
 extern void lease_get_mtime(struct inode *, struct timespec *time);
 extern int generic_setlease(struct file *, long, struct file_lock **, void **aux);
 extern int vfs_setlease(struct file *, long, struct file_lock **, void **aux);
-extern int lease_modify(struct file_lock **, int);
+extern int lease_modify(struct file_lock **, int, struct list_head *);
 #else /* !CONFIG_FILE_LOCKING */
 static inline int fcntl_getlk(struct file *file, unsigned int cmd,
 			      struct flock __user *user)
@@ -1112,7 +1112,8 @@ static inline int vfs_setlease(struct file *filp, long arg,
 	return -EINVAL;
 }
 
-static inline int lease_modify(struct file_lock **before, int arg)
+static inline int lease_modify(struct file_lock **before, int arg,
+			       struct list_head *dispose)
 {
 	return -EINVAL;
 }
-- 
1.9.3


WARNING: multiple messages have this Message-ID (diff)
From: Jeff Layton <jlayton@primarydata.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 09/10] locks: move freeing of leases outside of i_lock
Date: Sat, 23 Aug 2014 10:41:17 -0400	[thread overview]
Message-ID: <1408804878-1331-10-git-send-email-jlayton@primarydata.com> (raw)
In-Reply-To: <1408804878-1331-1-git-send-email-jlayton@primarydata.com>

There was only one place where we still could free a file_lock while
holding the i_lock -- lease_modify. Add a new list_head argument to the
lm_change operation, pass in a private list when calling it, and fix
those callers to dispose of the list once the lock has been dropped.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
---
 fs/locks.c          | 35 ++++++++++++++++++++++-------------
 fs/nfsd/nfs4state.c |  6 +++---
 include/linux/fs.h  |  7 ++++---
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 49210d5cbf41..98907cecaa44 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1297,7 +1297,7 @@ static void lease_clear_pending(struct file_lock *fl, int arg)
 }
 
 /* We already had a lease on this file; just change its type */
-int lease_modify(struct file_lock **before, int arg)
+int lease_modify(struct file_lock **before, int arg, struct list_head *dispose)
 {
 	struct file_lock *fl = *before;
 	int error = assign_type(fl, arg);
@@ -1316,7 +1316,7 @@ int lease_modify(struct file_lock **before, int arg)
 			printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
 			fl->fl_fasync = NULL;
 		}
-		locks_delete_lock(before, NULL);
+		locks_delete_lock(before, dispose);
 	}
 	return 0;
 }
@@ -1330,7 +1330,7 @@ static bool past_time(unsigned long then)
 	return time_after(jiffies, then);
 }
 
-static void time_out_leases(struct inode *inode)
+static void time_out_leases(struct inode *inode, struct list_head *dispose)
 {
 	struct file_lock **before;
 	struct file_lock *fl;
@@ -1341,9 +1341,9 @@ static void time_out_leases(struct inode *inode)
 	while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
 		trace_time_out_leases(inode, fl);
 		if (past_time(fl->fl_downgrade_time))
-			lease_modify(before, F_RDLCK);
+			lease_modify(before, F_RDLCK, dispose);
 		if (past_time(fl->fl_break_time))
-			lease_modify(before, F_UNLCK);
+			lease_modify(before, F_UNLCK, dispose);
 		if (fl == *before)	/* lease_modify may have freed fl */
 			before = &fl->fl_next;
 	}
@@ -1378,6 +1378,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 	int i_have_this_lease = 0;
 	bool lease_conflict = false;
 	int want_write = (mode & O_ACCMODE) != O_RDONLY;
+	LIST_HEAD(dispose);
 
 	new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
 	if (IS_ERR(new_fl))
@@ -1386,7 +1387,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
 
 	spin_lock(&inode->i_lock);
 
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	flock = inode->i_flock;
 	if ((flock == NULL) || !IS_LEASE(flock))
@@ -1441,6 +1442,7 @@ restart:
 	locks_insert_block(flock, new_fl);
 	trace_break_lease_block(inode, new_fl);
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	error = wait_event_interruptible_timeout(new_fl->fl_wait,
 						!new_fl->fl_next, break_time);
 	spin_lock(&inode->i_lock);
@@ -1448,7 +1450,7 @@ restart:
 	locks_delete_block(new_fl);
 	if (error >= 0) {
 		if (error == 0)
-			time_out_leases(inode);
+			time_out_leases(inode, &dispose);
 		/*
 		 * Wait for the next conflicting lease that has not been
 		 * broken yet
@@ -1463,6 +1465,7 @@ restart:
 
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	locks_free_lock(new_fl);
 	return error;
 }
@@ -1527,9 +1530,10 @@ int fcntl_getlease(struct file *filp)
 	struct file_lock *fl;
 	struct inode *inode = file_inode(filp);
 	int type = F_UNLCK;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(file_inode(filp));
+	time_out_leases(file_inode(filp), &dispose);
 	for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl);
 			fl = fl->fl_next) {
 		if (fl->fl_file == filp) {
@@ -1538,6 +1542,7 @@ int fcntl_getlease(struct file *filp)
 		}
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return type;
 }
 
@@ -1575,6 +1580,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	struct inode *inode = dentry->d_inode;
 	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
 	int error;
+	LIST_HEAD(dispose);
 
 	lease = *flp;
 	trace_generic_add_lease(inode, lease);
@@ -1598,7 +1604,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 	}
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 
 	error = check_conflicting_open(dentry, arg);
 	if (error)
@@ -1636,7 +1642,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **au
 
 	if (my_before != NULL) {
 		lease = *my_before;
-		error = lease->fl_lmops->lm_change(my_before, arg);
+		error = lease->fl_lmops->lm_change(my_before, arg, &dispose);
 		if (error)
 			goto out;
 		goto out_setup;
@@ -1666,6 +1672,7 @@ out_setup:
 		lease->fl_lmops->lm_setup(lease, aux);
 out:
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	if (is_deleg)
 		mutex_unlock(&inode->i_mutex);
 	if (!error && !my_before)
@@ -1682,17 +1689,19 @@ static int generic_delete_lease(struct file *filp)
 	struct file_lock *fl, **before;
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
+	LIST_HEAD(dispose);
 
 	spin_lock(&inode->i_lock);
-	time_out_leases(inode);
+	time_out_leases(inode, &dispose);
 	for (before = &inode->i_flock;
 			((fl = *before) != NULL) && IS_LEASE(fl);
 			before = &fl->fl_next) {
 		if (fl->fl_file != filp)
 			continue;
-		error = fl->fl_lmops->lm_change(before, F_UNLCK);
+		error = fl->fl_lmops->lm_change(before, F_UNLCK, &dispose);
 	}
 	spin_unlock(&inode->i_lock);
+	locks_dispose_list(&dispose);
 	return error;
 }
 
@@ -2388,7 +2397,7 @@ void locks_remove_file(struct file *filp)
 	while ((fl = *before) != NULL) {
 		if (fl->fl_file == filp) {
 			if (IS_LEASE(fl)) {
-				lease_modify(before, F_UNLCK);
+				lease_modify(before, F_UNLCK, &dispose);
 				continue;
 			}
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6af5d0890373..623576301e38 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3423,11 +3423,11 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
 	spin_unlock(&fp->fi_lock);
 }
 
-static
-int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
+static int
+nfsd_change_deleg_cb(struct file_lock **onlist, int arg, struct list_head *dispose)
 {
 	if (arg & F_UNLCK)
-		return lease_modify(onlist, arg);
+		return lease_modify(onlist, arg, dispose);
 	else
 		return -EAGAIN;
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 70d22c12924f..e3dbcf269cd2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -873,7 +873,7 @@ struct lock_manager_operations {
 	void (*lm_notify)(struct file_lock *);	/* unblock callback */
 	int (*lm_grant)(struct file_lock *, int);
 	void (*lm_break)(struct file_lock *);
-	int (*lm_change)(struct file_lock **, int);
+	int (*lm_change)(struct file_lock **, int, struct list_head *);
 	void (*lm_setup)(struct file_lock *, void **);
 };
 
@@ -985,7 +985,7 @@ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int t
 extern void lease_get_mtime(struct inode *, struct timespec *time);
 extern int generic_setlease(struct file *, long, struct file_lock **, void **aux);
 extern int vfs_setlease(struct file *, long, struct file_lock **, void **aux);
-extern int lease_modify(struct file_lock **, int);
+extern int lease_modify(struct file_lock **, int, struct list_head *);
 #else /* !CONFIG_FILE_LOCKING */
 static inline int fcntl_getlk(struct file *file, unsigned int cmd,
 			      struct flock __user *user)
@@ -1112,7 +1112,8 @@ static inline int vfs_setlease(struct file *filp, long arg,
 	return -EINVAL;
 }
 
-static inline int lease_modify(struct file_lock **before, int arg)
+static inline int lease_modify(struct file_lock **before, int arg,
+			       struct list_head *dispose)
 {
 	return -EINVAL;
 }
-- 
1.9.3



  parent reply	other threads:[~2014-08-23 14:41 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-23 14:41 [PATCH 00/10] locks/nfsd: internal lease API overhaul Jeff Layton
2014-08-23 14:41 ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41 ` Jeff Layton
2014-08-23 14:41 ` [PATCH 04/10] locks: clean up vfs_setlease kerneldoc comments Jeff Layton
2014-08-23 14:41   ` [Cluster-devel] " Jeff Layton
2014-08-24 15:51   ` Christoph Hellwig
2014-08-24 15:51     ` [Cluster-devel] " Christoph Hellwig
     [not found]     ` <20140824155117.GC15908-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-25 20:11       ` J. Bruce Fields
2014-08-25 20:11         ` [Cluster-devel] " J. Bruce Fields
2014-08-25 20:11         ` J. Bruce Fields
2014-08-23 14:41 ` [PATCH 07/10] locks: define a lm_setup handler for leases Jeff Layton
2014-08-23 14:41   ` [Cluster-devel] " Jeff Layton
     [not found]   ` <1408804878-1331-8-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 15:58     ` Christoph Hellwig
2014-08-24 15:58       ` [Cluster-devel] " Christoph Hellwig
2014-08-24 15:58       ` Christoph Hellwig
2014-08-25  1:19       ` Jeff Layton
2014-08-25  1:19         ` [Cluster-devel] " Jeff Layton
2014-08-26 13:58         ` Christoph Hellwig
2014-08-26 13:58           ` [Cluster-devel] " Christoph Hellwig
2014-08-23 14:41 ` [PATCH 08/10] locks: move i_lock acquisition into generic_*_lease handlers Jeff Layton
2014-08-23 14:41   ` [Cluster-devel] " Jeff Layton
     [not found]   ` <1408804878-1331-9-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 16:06     ` Christoph Hellwig
2014-08-24 16:06       ` [Cluster-devel] " Christoph Hellwig
2014-08-24 16:06       ` Christoph Hellwig
     [not found]       ` <20140824160634.GG15908-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-24 16:11         ` Christoph Hellwig
2014-08-24 16:11           ` [Cluster-devel] " Christoph Hellwig
2014-08-24 16:11           ` Christoph Hellwig
     [not found]           ` <20140824161134.GJ15908-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-31 14:51             ` Jeff Layton
2014-08-31 14:51               ` [Cluster-devel] " Jeff Layton
2014-08-31 14:51               ` Jeff Layton
2014-08-25  1:36         ` Jeff Layton
2014-08-25  1:36           ` [Cluster-devel] " Jeff Layton
2014-08-25  1:36           ` Jeff Layton
     [not found] ` <1408804878-1331-1-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-23 14:41   ` [PATCH 01/10] locks: close potential race in lease_get_mtime Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-2-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 15:48       ` Christoph Hellwig
2014-08-24 15:48         ` [Cluster-devel] " Christoph Hellwig
2014-08-24 15:48         ` Christoph Hellwig
2014-08-25 20:01     ` J. Bruce Fields
2014-08-25 20:01       ` [Cluster-devel] " J. Bruce Fields
2014-08-23 14:41   ` [PATCH 02/10] nfsd: fix potential lease memory leak in nfs4_setlease Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-3-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 15:48       ` Christoph Hellwig
2014-08-24 15:48         ` [Cluster-devel] " Christoph Hellwig
2014-08-24 15:48         ` Christoph Hellwig
2014-08-23 14:41   ` [PATCH 03/10] locks: generic_delete_lease doesn't need a file_lock at all Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-4-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24  1:27       ` Christoph Hellwig
2014-08-24  1:27         ` [Cluster-devel] " Christoph Hellwig
2014-08-24  1:27         ` Christoph Hellwig
     [not found]         ` <20140824012757.GA21609-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-24 10:09           ` Jeff Layton
2014-08-24 10:09             ` [Cluster-devel] " Jeff Layton
2014-08-24 10:09             ` Jeff Layton
2014-08-23 14:41   ` [PATCH 05/10] nfsd: don't keep a pointer to the lease in nfs4_file Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-6-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 15:51       ` Christoph Hellwig
2014-08-24 15:51         ` [Cluster-devel] " Christoph Hellwig
2014-08-24 15:51         ` Christoph Hellwig
2014-08-23 14:41   ` [PATCH 06/10] locks: plumb an "aux" pointer into the setlease routines Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-7-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24  1:33       ` Christoph Hellwig
2014-08-24  1:33         ` [Cluster-devel] " Christoph Hellwig
2014-08-24  1:33         ` Christoph Hellwig
     [not found]         ` <20140824013305.GB21609-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-24 10:08           ` Jeff Layton
2014-08-24 10:08             ` [Cluster-devel] " Jeff Layton
2014-08-24 10:08             ` Jeff Layton
     [not found]             ` <20140824060801.5402880c-08S845evdOaAjSkqwZiSMmfYqLom42DlXqFh9Ls21Oc@public.gmane.org>
2014-08-24 15:54               ` Christoph Hellwig
2014-08-24 15:54                 ` [Cluster-devel] " Christoph Hellwig
2014-08-24 15:54                 ` Christoph Hellwig
2014-08-25 20:28       ` J. Bruce Fields
2014-08-25 20:28         ` [Cluster-devel] " J. Bruce Fields
2014-08-25 20:28         ` J. Bruce Fields
     [not found]         ` <20140825202852.GD21957-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2014-08-26 10:53           ` Jeff Layton
2014-08-26 10:53             ` [Cluster-devel] " Jeff Layton
2014-08-26 10:53             ` Jeff Layton
2014-08-23 14:41   ` Jeff Layton [this message]
2014-08-23 14:41     ` [Cluster-devel] [PATCH 09/10] locks: move freeing of leases outside of i_lock Jeff Layton
2014-08-23 14:41     ` Jeff Layton
     [not found]     ` <1408804878-1331-10-git-send-email-jlayton-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2014-08-24 16:08       ` Christoph Hellwig
2014-08-24 16:08         ` [Cluster-devel] " Christoph Hellwig
2014-08-24 16:08         ` Christoph Hellwig
     [not found]         ` <20140824160804.GH15908-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-25  1:35           ` Jeff Layton
2014-08-25  1:35             ` [Cluster-devel] " Jeff Layton
2014-08-25  1:35             ` Jeff Layton
2014-08-23 14:41   ` [PATCH 10/10] locks: update Documentation/filesystems with lease API changes Jeff Layton
2014-08-23 14:41     ` [Cluster-devel] " Jeff Layton
2014-08-23 14:41     ` Jeff Layton
2014-08-24 16:10   ` [PATCH 00/10] locks/nfsd: internal lease API overhaul Christoph Hellwig
2014-08-24 16:10     ` [Cluster-devel] " Christoph Hellwig
2014-08-24 16:10     ` Christoph Hellwig
     [not found]     ` <20140824161046.GI15908-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2014-08-25  1:43       ` Jeff Layton
2014-08-25  1:43         ` [Cluster-devel] " Jeff Layton
2014-08-25  1:43         ` Jeff Layton
     [not found]         ` <20140824214301.61019123-08S845evdOaAjSkqwZiSMmfYqLom42DlXqFh9Ls21Oc@public.gmane.org>
2014-08-26 13:59           ` Christoph Hellwig
2014-08-26 13:59             ` [Cluster-devel] " Christoph Hellwig
2014-08-26 13:59             ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1408804878-1331-10-git-send-email-jlayton@primarydata.com \
    --to=jlayton-7i+n7zu2hftekmmhf/gkza@public.gmane.org \
    --cc=bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org \
    --cc=cluster-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.