diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /fs/nfs | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/inode.c | 17 | ||||
-rw-r--r-- | fs/nfs/internal.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs42proc.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4file.c | 59 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 1 | ||||
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 5 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 2 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 60 |
10 files changed, 80 insertions, 73 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e10d833..c7e8b87da5b2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -75,11 +75,11 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr) | |||
75 | * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks | 75 | * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks |
76 | * @word: long word containing the bit lock | 76 | * @word: long word containing the bit lock |
77 | */ | 77 | */ |
78 | int nfs_wait_bit_killable(struct wait_bit_key *key) | 78 | int nfs_wait_bit_killable(struct wait_bit_key *key, int mode) |
79 | { | 79 | { |
80 | if (fatal_signal_pending(current)) | ||
81 | return -ERESTARTSYS; | ||
82 | freezable_schedule_unsafe(); | 80 | freezable_schedule_unsafe(); |
81 | if (signal_pending_state(mode, current)) | ||
82 | return -ERESTARTSYS; | ||
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); | 85 | EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); |
@@ -618,7 +618,10 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, | |||
618 | nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); | 618 | nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); |
619 | nfs_vmtruncate(inode, attr->ia_size); | 619 | nfs_vmtruncate(inode, attr->ia_size); |
620 | } | 620 | } |
621 | nfs_update_inode(inode, fattr); | 621 | if (fattr->valid) |
622 | nfs_update_inode(inode, fattr); | ||
623 | else | ||
624 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; | ||
622 | spin_unlock(&inode->i_lock); | 625 | spin_unlock(&inode->i_lock); |
623 | } | 626 | } |
624 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); | 627 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); |
@@ -1824,7 +1827,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1824 | if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0) | 1827 | if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0) |
1825 | nfsi->attr_gencount = fattr->gencount; | 1828 | nfsi->attr_gencount = fattr->gencount; |
1826 | } | 1829 | } |
1827 | invalid &= ~NFS_INO_INVALID_ATTR; | 1830 | |
1831 | /* Don't declare attrcache up to date if there were no attrs! */ | ||
1832 | if (fattr->valid != 0) | ||
1833 | invalid &= ~NFS_INO_INVALID_ATTR; | ||
1834 | |||
1828 | /* Don't invalidate the data if we were to blame */ | 1835 | /* Don't invalidate the data if we were to blame */ |
1829 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1836 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1830 | || S_ISLNK(inode->i_mode))) | 1837 | || S_ISLNK(inode->i_mode))) |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 56cfde26fb9c..9dea85f7f918 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -379,7 +379,7 @@ extern int nfs_drop_inode(struct inode *); | |||
379 | extern void nfs_clear_inode(struct inode *); | 379 | extern void nfs_clear_inode(struct inode *); |
380 | extern void nfs_evict_inode(struct inode *); | 380 | extern void nfs_evict_inode(struct inode *); |
381 | void nfs_zap_acl_cache(struct inode *inode); | 381 | void nfs_zap_acl_cache(struct inode *inode); |
382 | extern int nfs_wait_bit_killable(struct wait_bit_key *key); | 382 | extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); |
383 | 383 | ||
384 | /* super.c */ | 384 | /* super.c */ |
385 | extern const struct super_operations nfs_sops; | 385 | extern const struct super_operations nfs_sops; |
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 3e92a3cde15d..6b1ce9825430 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "pnfs.h" | 14 | #include "pnfs.h" |
15 | #include "internal.h" | 15 | #include "internal.h" |
16 | 16 | ||
17 | #define NFSDBG_FACILITY NFSDBG_PNFS | 17 | #define NFSDBG_FACILITY NFSDBG_PROC |
18 | 18 | ||
19 | static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file, | 19 | static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file, |
20 | fmode_t fmode) | 20 | fmode_t fmode) |
@@ -284,6 +284,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, | |||
284 | .dst_fh = NFS_FH(dst_inode), | 284 | .dst_fh = NFS_FH(dst_inode), |
285 | .src_offset = src_offset, | 285 | .src_offset = src_offset, |
286 | .dst_offset = dst_offset, | 286 | .dst_offset = dst_offset, |
287 | .count = count, | ||
287 | .dst_bitmask = server->cache_consistency_bitmask, | 288 | .dst_bitmask = server->cache_consistency_bitmask, |
288 | }; | 289 | }; |
289 | struct nfs42_clone_res res = { | 290 | struct nfs42_clone_res res = { |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 223bedda64ae..10410e8b5853 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) | |||
33 | return ret; | 33 | return ret; |
34 | idr_preload(GFP_KERNEL); | 34 | idr_preload(GFP_KERNEL); |
35 | spin_lock(&nn->nfs_client_lock); | 35 | spin_lock(&nn->nfs_client_lock); |
36 | ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT); | 36 | ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT); |
37 | if (ret >= 0) | 37 | if (ret >= 0) |
38 | clp->cl_cb_ident = ret; | 38 | clp->cl_cb_ident = ret; |
39 | spin_unlock(&nn->nfs_client_lock); | 39 | spin_unlock(&nn->nfs_client_lock); |
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 4aa571956cd6..db9b5fea5b3e 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/file.h> | 7 | #include <linux/file.h> |
8 | #include <linux/falloc.h> | 8 | #include <linux/falloc.h> |
9 | #include <linux/nfs_fs.h> | 9 | #include <linux/nfs_fs.h> |
10 | #include <uapi/linux/btrfs.h> /* BTRFS_IOC_CLONE/BTRFS_IOC_CLONE_RANGE */ | ||
10 | #include "delegation.h" | 11 | #include "delegation.h" |
11 | #include "internal.h" | 12 | #include "internal.h" |
12 | #include "iostat.h" | 13 | #include "iostat.h" |
@@ -203,6 +204,7 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd, | |||
203 | struct fd src_file; | 204 | struct fd src_file; |
204 | struct inode *src_inode; | 205 | struct inode *src_inode; |
205 | unsigned int bs = server->clone_blksize; | 206 | unsigned int bs = server->clone_blksize; |
207 | bool same_inode = false; | ||
206 | int ret; | 208 | int ret; |
207 | 209 | ||
208 | /* dst file must be opened for writing */ | 210 | /* dst file must be opened for writing */ |
@@ -221,10 +223,8 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd, | |||
221 | 223 | ||
222 | src_inode = file_inode(src_file.file); | 224 | src_inode = file_inode(src_file.file); |
223 | 225 | ||
224 | /* src and dst must be different files */ | ||
225 | ret = -EINVAL; | ||
226 | if (src_inode == dst_inode) | 226 | if (src_inode == dst_inode) |
227 | goto out_fput; | 227 | same_inode = true; |
228 | 228 | ||
229 | /* src file must be opened for reading */ | 229 | /* src file must be opened for reading */ |
230 | if (!(src_file.file->f_mode & FMODE_READ)) | 230 | if (!(src_file.file->f_mode & FMODE_READ)) |
@@ -249,8 +249,16 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd, | |||
249 | goto out_fput; | 249 | goto out_fput; |
250 | } | 250 | } |
251 | 251 | ||
252 | /* verify if ranges are overlapped within the same file */ | ||
253 | if (same_inode) { | ||
254 | if (dst_off + count > src_off && dst_off < src_off + count) | ||
255 | goto out_fput; | ||
256 | } | ||
257 | |||
252 | /* XXX: do we lock at all? what if server needs CB_RECALL_LAYOUT? */ | 258 | /* XXX: do we lock at all? what if server needs CB_RECALL_LAYOUT? */ |
253 | if (dst_inode < src_inode) { | 259 | if (same_inode) { |
260 | mutex_lock(&src_inode->i_mutex); | ||
261 | } else if (dst_inode < src_inode) { | ||
254 | mutex_lock_nested(&dst_inode->i_mutex, I_MUTEX_PARENT); | 262 | mutex_lock_nested(&dst_inode->i_mutex, I_MUTEX_PARENT); |
255 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); | 263 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); |
256 | } else { | 264 | } else { |
@@ -275,7 +283,9 @@ nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd, | |||
275 | truncate_inode_pages_range(&dst_inode->i_data, dst_off, dst_off + count - 1); | 283 | truncate_inode_pages_range(&dst_inode->i_data, dst_off, dst_off + count - 1); |
276 | 284 | ||
277 | out_unlock: | 285 | out_unlock: |
278 | if (dst_inode < src_inode) { | 286 | if (same_inode) { |
287 | mutex_unlock(&src_inode->i_mutex); | ||
288 | } else if (dst_inode < src_inode) { | ||
279 | mutex_unlock(&src_inode->i_mutex); | 289 | mutex_unlock(&src_inode->i_mutex); |
280 | mutex_unlock(&dst_inode->i_mutex); | 290 | mutex_unlock(&dst_inode->i_mutex); |
281 | } else { | 291 | } else { |
@@ -291,46 +301,31 @@ out_drop_write: | |||
291 | 301 | ||
292 | static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp) | 302 | static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp) |
293 | { | 303 | { |
294 | struct nfs_ioctl_clone_range_args args; | 304 | struct btrfs_ioctl_clone_range_args args; |
295 | 305 | ||
296 | if (copy_from_user(&args, argp, sizeof(args))) | 306 | if (copy_from_user(&args, argp, sizeof(args))) |
297 | return -EFAULT; | 307 | return -EFAULT; |
298 | 308 | ||
299 | return nfs42_ioctl_clone(dst_file, args.src_fd, args.src_off, args.dst_off, args.count); | 309 | return nfs42_ioctl_clone(dst_file, args.src_fd, args.src_offset, |
300 | } | 310 | args.dest_offset, args.src_length); |
301 | #else | ||
302 | static long nfs42_ioctl_clone(struct file *dst_file, unsigned long srcfd, | ||
303 | u64 src_off, u64 dst_off, u64 count) | ||
304 | { | ||
305 | return -ENOTTY; | ||
306 | } | ||
307 | |||
308 | static long nfs42_ioctl_clone_range(struct file *dst_file, void __user *argp) | ||
309 | { | ||
310 | return -ENOTTY; | ||
311 | } | 311 | } |
312 | #endif /* CONFIG_NFS_V4_2 */ | ||
313 | 312 | ||
314 | long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 313 | long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
315 | { | 314 | { |
316 | void __user *argp = (void __user *)arg; | 315 | void __user *argp = (void __user *)arg; |
317 | 316 | ||
318 | switch (cmd) { | 317 | switch (cmd) { |
319 | case NFS_IOC_CLONE: | 318 | case BTRFS_IOC_CLONE: |
320 | return nfs42_ioctl_clone(file, arg, 0, 0, 0); | 319 | return nfs42_ioctl_clone(file, arg, 0, 0, 0); |
321 | case NFS_IOC_CLONE_RANGE: | 320 | case BTRFS_IOC_CLONE_RANGE: |
322 | return nfs42_ioctl_clone_range(file, argp); | 321 | return nfs42_ioctl_clone_range(file, argp); |
323 | } | 322 | } |
324 | 323 | ||
325 | return -ENOTTY; | 324 | return -ENOTTY; |
326 | } | 325 | } |
326 | #endif /* CONFIG_NFS_V4_2 */ | ||
327 | 327 | ||
328 | const struct file_operations nfs4_file_operations = { | 328 | const struct file_operations nfs4_file_operations = { |
329 | #ifdef CONFIG_NFS_V4_2 | ||
330 | .llseek = nfs4_file_llseek, | ||
331 | #else | ||
332 | .llseek = nfs_file_llseek, | ||
333 | #endif | ||
334 | .read_iter = nfs_file_read, | 329 | .read_iter = nfs_file_read, |
335 | .write_iter = nfs_file_write, | 330 | .write_iter = nfs_file_write, |
336 | .mmap = nfs_file_mmap, | 331 | .mmap = nfs_file_mmap, |
@@ -342,14 +337,14 @@ const struct file_operations nfs4_file_operations = { | |||
342 | .flock = nfs_flock, | 337 | .flock = nfs_flock, |
343 | .splice_read = nfs_file_splice_read, | 338 | .splice_read = nfs_file_splice_read, |
344 | .splice_write = iter_file_splice_write, | 339 | .splice_write = iter_file_splice_write, |
345 | #ifdef CONFIG_NFS_V4_2 | ||
346 | .fallocate = nfs42_fallocate, | ||
347 | #endif /* CONFIG_NFS_V4_2 */ | ||
348 | .check_flags = nfs_check_flags, | 340 | .check_flags = nfs_check_flags, |
349 | .setlease = simple_nosetlease, | 341 | .setlease = simple_nosetlease, |
350 | #ifdef CONFIG_COMPAT | 342 | #ifdef CONFIG_NFS_V4_2 |
343 | .llseek = nfs4_file_llseek, | ||
344 | .fallocate = nfs42_fallocate, | ||
351 | .unlocked_ioctl = nfs4_ioctl, | 345 | .unlocked_ioctl = nfs4_ioctl, |
352 | #else | ||
353 | .compat_ioctl = nfs4_ioctl, | 346 | .compat_ioctl = nfs4_ioctl, |
354 | #endif /* CONFIG_COMPAT */ | 347 | #else |
348 | .llseek = nfs_file_llseek, | ||
349 | #endif | ||
355 | }; | 350 | }; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 765a03559363..89818036f035 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -7866,7 +7866,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) | |||
7866 | spin_unlock(&inode->i_lock); | 7866 | spin_unlock(&inode->i_lock); |
7867 | goto out_restart; | 7867 | goto out_restart; |
7868 | } | 7868 | } |
7869 | if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN) | 7869 | if (nfs4_async_handle_error(task, server, state, &lgp->timeout) == -EAGAIN) |
7870 | goto out_restart; | 7870 | goto out_restart; |
7871 | out: | 7871 | out: |
7872 | dprintk("<-- %s\n", __func__); | 7872 | dprintk("<-- %s\n", __func__); |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index dfed4f5c8fcc..4e4441216804 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -3615,6 +3615,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3615 | status = 0; | 3615 | status = 0; |
3616 | if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) | 3616 | if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) |
3617 | goto out; | 3617 | goto out; |
3618 | bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS; | ||
3618 | status = -EIO; | 3619 | status = -EIO; |
3619 | /* Ignore borken servers that return unrequested attrs */ | 3620 | /* Ignore borken servers that return unrequested attrs */ |
3620 | if (unlikely(res == NULL)) | 3621 | if (unlikely(res == NULL)) |
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 5c0c6b58157f..9aebffb40505 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -476,10 +476,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
476 | } | 476 | } |
477 | unlock_page(page); | 477 | unlock_page(page); |
478 | } | 478 | } |
479 | if (PageDirty(page) || PageWriteback(page)) | 479 | *uptodate = PageUptodate(page); |
480 | *uptodate = true; | ||
481 | else | ||
482 | *uptodate = PageUptodate(page); | ||
483 | dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate); | 480 | dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate); |
484 | return page; | 481 | return page; |
485 | } | 482 | } |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index fe3ddd20ff89..452a011ba0d8 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -129,7 +129,7 @@ __nfs_iocounter_wait(struct nfs_io_counter *c) | |||
129 | set_bit(NFS_IO_INPROGRESS, &c->flags); | 129 | set_bit(NFS_IO_INPROGRESS, &c->flags); |
130 | if (atomic_read(&c->io_count) == 0) | 130 | if (atomic_read(&c->io_count) == 0) |
131 | break; | 131 | break; |
132 | ret = nfs_wait_bit_killable(&q.key); | 132 | ret = nfs_wait_bit_killable(&q.key, TASK_KILLABLE); |
133 | } while (atomic_read(&c->io_count) != 0 && !ret); | 133 | } while (atomic_read(&c->io_count) != 0 && !ret); |
134 | finish_wait(wq, &q.wait); | 134 | finish_wait(wq, &q.wait); |
135 | return ret; | 135 | return ret; |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 93496c059837..bec0384499f7 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
872 | 872 | ||
873 | dprintk("--> %s\n", __func__); | 873 | dprintk("--> %s\n", __func__); |
874 | 874 | ||
875 | lgp = kzalloc(sizeof(*lgp), gfp_flags); | 875 | /* |
876 | if (lgp == NULL) | 876 | * Synchronously retrieve layout information from server and |
877 | return NULL; | 877 | * store in lseg. If we race with a concurrent seqid morphing |
878 | * op, then re-send the LAYOUTGET. | ||
879 | */ | ||
880 | do { | ||
881 | lgp = kzalloc(sizeof(*lgp), gfp_flags); | ||
882 | if (lgp == NULL) | ||
883 | return NULL; | ||
884 | |||
885 | i_size = i_size_read(ino); | ||
886 | |||
887 | lgp->args.minlength = PAGE_CACHE_SIZE; | ||
888 | if (lgp->args.minlength > range->length) | ||
889 | lgp->args.minlength = range->length; | ||
890 | if (range->iomode == IOMODE_READ) { | ||
891 | if (range->offset >= i_size) | ||
892 | lgp->args.minlength = 0; | ||
893 | else if (i_size - range->offset < lgp->args.minlength) | ||
894 | lgp->args.minlength = i_size - range->offset; | ||
895 | } | ||
896 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; | ||
897 | lgp->args.range = *range; | ||
898 | lgp->args.type = server->pnfs_curr_ld->id; | ||
899 | lgp->args.inode = ino; | ||
900 | lgp->args.ctx = get_nfs_open_context(ctx); | ||
901 | lgp->gfp_flags = gfp_flags; | ||
902 | lgp->cred = lo->plh_lc_cred; | ||
878 | 903 | ||
879 | i_size = i_size_read(ino); | 904 | lseg = nfs4_proc_layoutget(lgp, gfp_flags); |
905 | } while (lseg == ERR_PTR(-EAGAIN)); | ||
880 | 906 | ||
881 | lgp->args.minlength = PAGE_CACHE_SIZE; | ||
882 | if (lgp->args.minlength > range->length) | ||
883 | lgp->args.minlength = range->length; | ||
884 | if (range->iomode == IOMODE_READ) { | ||
885 | if (range->offset >= i_size) | ||
886 | lgp->args.minlength = 0; | ||
887 | else if (i_size - range->offset < lgp->args.minlength) | ||
888 | lgp->args.minlength = i_size - range->offset; | ||
889 | } | ||
890 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; | ||
891 | lgp->args.range = *range; | ||
892 | lgp->args.type = server->pnfs_curr_ld->id; | ||
893 | lgp->args.inode = ino; | ||
894 | lgp->args.ctx = get_nfs_open_context(ctx); | ||
895 | lgp->gfp_flags = gfp_flags; | ||
896 | lgp->cred = lo->plh_lc_cred; | ||
897 | |||
898 | /* Synchronously retrieve layout information from server and | ||
899 | * store in lseg. | ||
900 | */ | ||
901 | lseg = nfs4_proc_layoutget(lgp, gfp_flags); | ||
902 | if (IS_ERR(lseg)) { | 907 | if (IS_ERR(lseg)) { |
903 | switch (PTR_ERR(lseg)) { | 908 | switch (PTR_ERR(lseg)) { |
904 | case -ENOMEM: | 909 | case -ENOMEM: |
@@ -1461,11 +1466,11 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx, | |||
1461 | } | 1466 | } |
1462 | 1467 | ||
1463 | /* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */ | 1468 | /* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */ |
1464 | static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key) | 1469 | static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode) |
1465 | { | 1470 | { |
1466 | if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags)) | 1471 | if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags)) |
1467 | return 1; | 1472 | return 1; |
1468 | return nfs_wait_bit_killable(key); | 1473 | return nfs_wait_bit_killable(key, mode); |
1469 | } | 1474 | } |
1470 | 1475 | ||
1471 | static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) | 1476 | static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) |
@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) | |||
1687 | /* existing state ID, make sure the sequence number matches. */ | 1692 | /* existing state ID, make sure the sequence number matches. */ |
1688 | if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { | 1693 | if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { |
1689 | dprintk("%s forget reply due to sequence\n", __func__); | 1694 | dprintk("%s forget reply due to sequence\n", __func__); |
1695 | status = -EAGAIN; | ||
1690 | goto out_forget_reply; | 1696 | goto out_forget_reply; |
1691 | } | 1697 | } |
1692 | pnfs_set_layout_stateid(lo, &res->stateid, false); | 1698 | pnfs_set_layout_stateid(lo, &res->stateid, false); |