diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e072aeb34195..784c13485b3f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1091,6 +1091,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
1091 | { | 1091 | { |
1092 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 1092 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
1093 | struct nfs_lock_context *l_ctx; | 1093 | struct nfs_lock_context *l_ctx; |
1094 | struct file_lock_context *flctx = file_inode(file)->i_flctx; | ||
1094 | struct nfs_page *req; | 1095 | struct nfs_page *req; |
1095 | int do_flush, status; | 1096 | int do_flush, status; |
1096 | /* | 1097 | /* |
@@ -1109,12 +1110,9 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
1109 | do_flush = req->wb_page != page || req->wb_context != ctx; | 1110 | do_flush = req->wb_page != page || req->wb_context != ctx; |
1110 | /* for now, flush if more than 1 request in page_group */ | 1111 | /* for now, flush if more than 1 request in page_group */ |
1111 | do_flush |= req->wb_this_page != req; | 1112 | do_flush |= req->wb_this_page != req; |
1112 | if (l_ctx && ctx->dentry->d_inode->i_flock != NULL) { | 1113 | if (l_ctx && flctx && |
1113 | do_flush |= l_ctx->lockowner.l_owner != current->files | 1114 | !(list_empty_careful(&flctx->flc_posix) && |
1114 | || l_ctx->lockowner.l_pid != current->tgid; | 1115 | list_empty_careful(&flctx->flc_flock))) { |
1115 | } | ||
1116 | if (l_ctx && ctx->dentry->d_inode->i_flctx && | ||
1117 | !list_empty_careful(&ctx->dentry->d_inode->i_flctx->flc_flock)) { | ||
1118 | do_flush |= l_ctx->lockowner.l_owner != current->files | 1116 | do_flush |= l_ctx->lockowner.l_owner != current->files |
1119 | || l_ctx->lockowner.l_pid != current->tgid; | 1117 | || l_ctx->lockowner.l_pid != current->tgid; |
1120 | } | 1118 | } |
@@ -1202,26 +1200,24 @@ static int nfs_can_extend_write(struct file *file, struct page *page, struct ino | |||
1202 | return 0; | 1200 | return 0; |
1203 | if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) | 1201 | if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) |
1204 | return 1; | 1202 | return 1; |
1205 | if (!inode->i_flock && !flctx) | 1203 | if (!flctx || (list_empty_careful(&flctx->flc_flock) && |
1204 | list_empty_careful(&flctx->flc_posix))) | ||
1206 | return 0; | 1205 | return 0; |
1207 | 1206 | ||
1208 | /* Check to see if there are whole file write locks */ | 1207 | /* Check to see if there are whole file write locks */ |
1209 | spin_lock(&inode->i_lock); | ||
1210 | ret = 0; | 1208 | ret = 0; |
1211 | 1209 | spin_lock(&inode->i_lock); | |
1212 | fl = inode->i_flock; | 1210 | if (!list_empty(&flctx->flc_posix)) { |
1213 | if (fl && is_whole_file_wrlock(fl)) { | 1211 | fl = list_first_entry(&flctx->flc_posix, struct file_lock, |
1214 | ret = 1; | 1212 | fl_list); |
1215 | goto out; | 1213 | if (is_whole_file_wrlock(fl)) |
1216 | } | 1214 | ret = 1; |
1217 | 1215 | } else if (!list_empty(&flctx->flc_flock)) { | |
1218 | if (!list_empty(&flctx->flc_flock)) { | ||
1219 | fl = list_first_entry(&flctx->flc_flock, struct file_lock, | 1216 | fl = list_first_entry(&flctx->flc_flock, struct file_lock, |
1220 | fl_list); | 1217 | fl_list); |
1221 | if (fl->fl_type == F_WRLCK) | 1218 | if (fl->fl_type == F_WRLCK) |
1222 | ret = 1; | 1219 | ret = 1; |
1223 | } | 1220 | } |
1224 | out: | ||
1225 | spin_unlock(&inode->i_lock); | 1221 | spin_unlock(&inode->i_lock); |
1226 | return ret; | 1222 | return ret; |
1227 | } | 1223 | } |