aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/locks.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/locks.c b/fs/locks.c
index c528522862b1..c4215418bca3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -135,7 +135,7 @@
135 135
136static bool lease_breaking(struct file_lock *fl) 136static bool lease_breaking(struct file_lock *fl)
137{ 137{
138 return fl->fl_type & F_INPROGRESS; 138 return fl->fl_flags & FL_INPROGRESS;
139} 139}
140 140
141int leases_enable = 1; 141int leases_enable = 1;
@@ -1132,6 +1132,7 @@ int lease_modify(struct file_lock **before, int arg)
1132 1132
1133 if (error) 1133 if (error)
1134 return error; 1134 return error;
1135 fl->fl_flags &= ~FL_INPROGRESS;
1135 locks_wake_up_blocks(fl); 1136 locks_wake_up_blocks(fl);
1136 if (arg == F_UNLCK) 1137 if (arg == F_UNLCK)
1137 locks_delete_lock(before); 1138 locks_delete_lock(before);
@@ -1152,7 +1153,7 @@ static void time_out_leases(struct inode *inode)
1152 before = &fl->fl_next; 1153 before = &fl->fl_next;
1153 continue; 1154 continue;
1154 } 1155 }
1155 lease_modify(before, fl->fl_type & ~F_INPROGRESS); 1156 lease_modify(before, fl->fl_type);
1156 if (fl == *before) /* lease_modify may have freed fl */ 1157 if (fl == *before) /* lease_modify may have freed fl */
1157 before = &fl->fl_next; 1158 before = &fl->fl_next;
1158 } 1159 }
@@ -1193,13 +1194,13 @@ int __break_lease(struct inode *inode, unsigned int mode)
1193 1194
1194 if (want_write) { 1195 if (want_write) {
1195 /* If we want write access, we have to revoke any lease. */ 1196 /* If we want write access, we have to revoke any lease. */
1196 future = F_UNLCK | F_INPROGRESS; 1197 future = F_UNLCK;
1197 } else if (lease_breaking(flock)) { 1198 } else if (lease_breaking(flock)) {
1198 /* If the lease is already being broken, we just leave it */ 1199 /* If the lease is already being broken, we just leave it */
1199 future = flock->fl_type; 1200 future = flock->fl_type;
1200 } else if (flock->fl_type & F_WRLCK) { 1201 } else if (flock->fl_type & F_WRLCK) {
1201 /* Downgrade the exclusive lease to a read-only lease. */ 1202 /* Downgrade the exclusive lease to a read-only lease. */
1202 future = F_RDLCK | F_INPROGRESS; 1203 future = F_RDLCK;
1203 } else { 1204 } else {
1204 /* the existing lease was read-only, so we can read too. */ 1205 /* the existing lease was read-only, so we can read too. */
1205 goto out; 1206 goto out;
@@ -1221,6 +1222,7 @@ int __break_lease(struct inode *inode, unsigned int mode)
1221 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) { 1222 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) {
1222 if (fl->fl_type != future) { 1223 if (fl->fl_type != future) {
1223 fl->fl_type = future; 1224 fl->fl_type = future;
1225 fl->fl_flags |= FL_INPROGRESS;
1224 fl->fl_break_time = break_time; 1226 fl->fl_break_time = break_time;
1225 /* lease must have lmops break callback */ 1227 /* lease must have lmops break callback */
1226 fl->fl_lmops->lm_break(fl); 1228 fl->fl_lmops->lm_break(fl);
@@ -1319,7 +1321,7 @@ int fcntl_getlease(struct file *filp)
1319 for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl); 1321 for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl);
1320 fl = fl->fl_next) { 1322 fl = fl->fl_next) {
1321 if (fl->fl_file == filp) { 1323 if (fl->fl_file == filp) {
1322 type = fl->fl_type & ~F_INPROGRESS; 1324 type = fl->fl_type;
1323 break; 1325 break;
1324 } 1326 }
1325 } 1327 }
@@ -1384,7 +1386,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1384 before = &fl->fl_next) { 1386 before = &fl->fl_next) {
1385 if (fl->fl_file == filp) 1387 if (fl->fl_file == filp)
1386 my_before = before; 1388 my_before = before;
1387 else if (fl->fl_type == (F_INPROGRESS | F_UNLCK)) 1389 else if ((fl->fl_type == F_UNLCK) && lease_breaking(fl))
1388 /* 1390 /*
1389 * Someone is in the process of opening this 1391 * Someone is in the process of opening this
1390 * file for writing so we may not take an 1392 * file for writing so we may not take an