diff options
Diffstat (limited to 'fs')
45 files changed, 223 insertions, 191 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 06e8ff12b97c..4230252fd689 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/kmod.h> | 12 | #include <linux/kmod.h> |
13 | #include <linux/major.h> | 13 | #include <linux/major.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/device_cgroup.h> | 14 | #include <linux/device_cgroup.h> |
16 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
17 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index e9c874abc9e1..561438b6a50c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -204,7 +204,7 @@ static int readpage_nounlock(struct file *filp, struct page *page) | |||
204 | err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, | 204 | err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, |
205 | page->index << PAGE_CACHE_SHIFT, &len, | 205 | page->index << PAGE_CACHE_SHIFT, &len, |
206 | ci->i_truncate_seq, ci->i_truncate_size, | 206 | ci->i_truncate_seq, ci->i_truncate_size, |
207 | &page, 1); | 207 | &page, 1, 0); |
208 | if (err == -ENOENT) | 208 | if (err == -ENOENT) |
209 | err = 0; | 209 | err = 0; |
210 | if (err < 0) { | 210 | if (err < 0) { |
@@ -287,7 +287,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, | |||
287 | rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, | 287 | rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, |
288 | offset, &len, | 288 | offset, &len, |
289 | ci->i_truncate_seq, ci->i_truncate_size, | 289 | ci->i_truncate_seq, ci->i_truncate_size, |
290 | pages, nr_pages); | 290 | pages, nr_pages, 0); |
291 | if (rc == -ENOENT) | 291 | if (rc == -ENOENT) |
292 | rc = 0; | 292 | rc = 0; |
293 | if (rc < 0) | 293 | if (rc < 0) |
@@ -774,7 +774,7 @@ get_more_pages: | |||
774 | snapc, do_sync, | 774 | snapc, do_sync, |
775 | ci->i_truncate_seq, | 775 | ci->i_truncate_seq, |
776 | ci->i_truncate_size, | 776 | ci->i_truncate_size, |
777 | &inode->i_mtime, true, 1); | 777 | &inode->i_mtime, true, 1, 0); |
778 | max_pages = req->r_num_pages; | 778 | max_pages = req->r_num_pages; |
779 | 779 | ||
780 | alloc_page_vec(fsc, req); | 780 | alloc_page_vec(fsc, req); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 98ab13e2b71d..60d27bc9eb83 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1430,8 +1430,8 @@ static int try_nonblocking_invalidate(struct inode *inode) | |||
1430 | invalidating_gen == ci->i_rdcache_gen) { | 1430 | invalidating_gen == ci->i_rdcache_gen) { |
1431 | /* success. */ | 1431 | /* success. */ |
1432 | dout("try_nonblocking_invalidate %p success\n", inode); | 1432 | dout("try_nonblocking_invalidate %p success\n", inode); |
1433 | ci->i_rdcache_gen = 0; | 1433 | /* save any racing async invalidate some trouble */ |
1434 | ci->i_rdcache_revoking = 0; | 1434 | ci->i_rdcache_revoking = ci->i_rdcache_gen - 1; |
1435 | return 0; | 1435 | return 0; |
1436 | } | 1436 | } |
1437 | dout("try_nonblocking_invalidate %p failed\n", inode); | 1437 | dout("try_nonblocking_invalidate %p failed\n", inode); |
@@ -2273,8 +2273,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2273 | { | 2273 | { |
2274 | struct ceph_inode_info *ci = ceph_inode(inode); | 2274 | struct ceph_inode_info *ci = ceph_inode(inode); |
2275 | int mds = session->s_mds; | 2275 | int mds = session->s_mds; |
2276 | unsigned seq = le32_to_cpu(grant->seq); | 2276 | int seq = le32_to_cpu(grant->seq); |
2277 | unsigned issue_seq = le32_to_cpu(grant->issue_seq); | ||
2278 | int newcaps = le32_to_cpu(grant->caps); | 2277 | int newcaps = le32_to_cpu(grant->caps); |
2279 | int issued, implemented, used, wanted, dirty; | 2278 | int issued, implemented, used, wanted, dirty; |
2280 | u64 size = le64_to_cpu(grant->size); | 2279 | u64 size = le64_to_cpu(grant->size); |
@@ -2286,8 +2285,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2286 | int revoked_rdcache = 0; | 2285 | int revoked_rdcache = 0; |
2287 | int queue_invalidate = 0; | 2286 | int queue_invalidate = 0; |
2288 | 2287 | ||
2289 | dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n", | 2288 | dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", |
2290 | inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps)); | 2289 | inode, cap, mds, seq, ceph_cap_string(newcaps)); |
2291 | dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, | 2290 | dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, |
2292 | inode->i_size); | 2291 | inode->i_size); |
2293 | 2292 | ||
@@ -2383,7 +2382,6 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2383 | } | 2382 | } |
2384 | 2383 | ||
2385 | cap->seq = seq; | 2384 | cap->seq = seq; |
2386 | cap->issue_seq = issue_seq; | ||
2387 | 2385 | ||
2388 | /* file layout may have changed */ | 2386 | /* file layout may have changed */ |
2389 | ci->i_layout = grant->layout; | 2387 | ci->i_layout = grant->layout; |
@@ -2691,6 +2689,11 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, | |||
2691 | NULL /* no caps context */); | 2689 | NULL /* no caps context */); |
2692 | try_flush_caps(inode, session, NULL); | 2690 | try_flush_caps(inode, session, NULL); |
2693 | up_read(&mdsc->snap_rwsem); | 2691 | up_read(&mdsc->snap_rwsem); |
2692 | |||
2693 | /* make sure we re-request max_size, if necessary */ | ||
2694 | spin_lock(&inode->i_lock); | ||
2695 | ci->i_requested_max_size = 0; | ||
2696 | spin_unlock(&inode->i_lock); | ||
2694 | } | 2697 | } |
2695 | 2698 | ||
2696 | /* | 2699 | /* |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index e0a2dc6fcafc..7d447af84ec4 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -336,7 +336,10 @@ more: | |||
336 | if (req->r_reply_info.dir_end) { | 336 | if (req->r_reply_info.dir_end) { |
337 | kfree(fi->last_name); | 337 | kfree(fi->last_name); |
338 | fi->last_name = NULL; | 338 | fi->last_name = NULL; |
339 | fi->next_offset = 2; | 339 | if (ceph_frag_is_rightmost(frag)) |
340 | fi->next_offset = 2; | ||
341 | else | ||
342 | fi->next_offset = 0; | ||
340 | } else { | 343 | } else { |
341 | rinfo = &req->r_reply_info; | 344 | rinfo = &req->r_reply_info; |
342 | err = note_last_dentry(fi, | 345 | err = note_last_dentry(fi, |
@@ -355,18 +358,22 @@ more: | |||
355 | u64 pos = ceph_make_fpos(frag, off); | 358 | u64 pos = ceph_make_fpos(frag, off); |
356 | struct ceph_mds_reply_inode *in = | 359 | struct ceph_mds_reply_inode *in = |
357 | rinfo->dir_in[off - fi->offset].in; | 360 | rinfo->dir_in[off - fi->offset].in; |
361 | struct ceph_vino vino; | ||
362 | ino_t ino; | ||
363 | |||
358 | dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", | 364 | dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", |
359 | off, off - fi->offset, rinfo->dir_nr, pos, | 365 | off, off - fi->offset, rinfo->dir_nr, pos, |
360 | rinfo->dir_dname_len[off - fi->offset], | 366 | rinfo->dir_dname_len[off - fi->offset], |
361 | rinfo->dir_dname[off - fi->offset], in); | 367 | rinfo->dir_dname[off - fi->offset], in); |
362 | BUG_ON(!in); | 368 | BUG_ON(!in); |
363 | ftype = le32_to_cpu(in->mode) >> 12; | 369 | ftype = le32_to_cpu(in->mode) >> 12; |
370 | vino.ino = le64_to_cpu(in->ino); | ||
371 | vino.snap = le64_to_cpu(in->snapid); | ||
372 | ino = ceph_vino_to_ino(vino); | ||
364 | if (filldir(dirent, | 373 | if (filldir(dirent, |
365 | rinfo->dir_dname[off - fi->offset], | 374 | rinfo->dir_dname[off - fi->offset], |
366 | rinfo->dir_dname_len[off - fi->offset], | 375 | rinfo->dir_dname_len[off - fi->offset], |
367 | pos, | 376 | pos, ino, ftype) < 0) { |
368 | le64_to_cpu(in->ino), | ||
369 | ftype) < 0) { | ||
370 | dout("filldir stopping us...\n"); | 377 | dout("filldir stopping us...\n"); |
371 | return 0; | 378 | return 0; |
372 | } | 379 | } |
@@ -414,6 +421,7 @@ static void reset_readdir(struct ceph_file_info *fi) | |||
414 | fi->last_readdir = NULL; | 421 | fi->last_readdir = NULL; |
415 | } | 422 | } |
416 | kfree(fi->last_name); | 423 | kfree(fi->last_name); |
424 | fi->last_name = NULL; | ||
417 | fi->next_offset = 2; /* compensate for . and .. */ | 425 | fi->next_offset = 2; /* compensate for . and .. */ |
418 | if (fi->dentry) { | 426 | if (fi->dentry) { |
419 | dput(fi->dentry); | 427 | dput(fi->dentry); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index e77c28cf3690..8d79b8912e31 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -154,11 +154,13 @@ int ceph_open(struct inode *inode, struct file *file) | |||
154 | } | 154 | } |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * No need to block if we have any caps. Update wanted set | 157 | * No need to block if we have caps on the auth MDS (for |
158 | * write) or any MDS (for read). Update wanted set | ||
158 | * asynchronously. | 159 | * asynchronously. |
159 | */ | 160 | */ |
160 | spin_lock(&inode->i_lock); | 161 | spin_lock(&inode->i_lock); |
161 | if (__ceph_is_any_real_caps(ci)) { | 162 | if (__ceph_is_any_real_caps(ci) && |
163 | (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) { | ||
162 | int mds_wanted = __ceph_caps_mds_wanted(ci); | 164 | int mds_wanted = __ceph_caps_mds_wanted(ci); |
163 | int issued = __ceph_caps_issued(ci, NULL); | 165 | int issued = __ceph_caps_issued(ci, NULL); |
164 | 166 | ||
@@ -280,11 +282,12 @@ int ceph_release(struct inode *inode, struct file *file) | |||
280 | static int striped_read(struct inode *inode, | 282 | static int striped_read(struct inode *inode, |
281 | u64 off, u64 len, | 283 | u64 off, u64 len, |
282 | struct page **pages, int num_pages, | 284 | struct page **pages, int num_pages, |
283 | int *checkeof) | 285 | int *checkeof, bool align_to_pages) |
284 | { | 286 | { |
285 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 287 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
286 | struct ceph_inode_info *ci = ceph_inode(inode); | 288 | struct ceph_inode_info *ci = ceph_inode(inode); |
287 | u64 pos, this_len; | 289 | u64 pos, this_len; |
290 | int io_align, page_align; | ||
288 | int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ | 291 | int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ |
289 | int left, pages_left; | 292 | int left, pages_left; |
290 | int read; | 293 | int read; |
@@ -300,14 +303,19 @@ static int striped_read(struct inode *inode, | |||
300 | page_pos = pages; | 303 | page_pos = pages; |
301 | pages_left = num_pages; | 304 | pages_left = num_pages; |
302 | read = 0; | 305 | read = 0; |
306 | io_align = off & ~PAGE_MASK; | ||
303 | 307 | ||
304 | more: | 308 | more: |
309 | if (align_to_pages) | ||
310 | page_align = (pos - io_align) & ~PAGE_MASK; | ||
311 | else | ||
312 | page_align = pos & ~PAGE_MASK; | ||
305 | this_len = left; | 313 | this_len = left; |
306 | ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode), | 314 | ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode), |
307 | &ci->i_layout, pos, &this_len, | 315 | &ci->i_layout, pos, &this_len, |
308 | ci->i_truncate_seq, | 316 | ci->i_truncate_seq, |
309 | ci->i_truncate_size, | 317 | ci->i_truncate_size, |
310 | page_pos, pages_left); | 318 | page_pos, pages_left, page_align); |
311 | hit_stripe = this_len < left; | 319 | hit_stripe = this_len < left; |
312 | was_short = ret >= 0 && ret < this_len; | 320 | was_short = ret >= 0 && ret < this_len; |
313 | if (ret == -ENOENT) | 321 | if (ret == -ENOENT) |
@@ -374,26 +382,25 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, | |||
374 | dout("sync_read on file %p %llu~%u %s\n", file, off, len, | 382 | dout("sync_read on file %p %llu~%u %s\n", file, off, len, |
375 | (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); | 383 | (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); |
376 | 384 | ||
377 | if (file->f_flags & O_DIRECT) { | 385 | if (file->f_flags & O_DIRECT) |
378 | pages = ceph_get_direct_page_vector(data, num_pages, off, len); | 386 | pages = ceph_get_direct_page_vector(data, num_pages); |
379 | 387 | else | |
380 | /* | ||
381 | * flush any page cache pages in this range. this | ||
382 | * will make concurrent normal and O_DIRECT io slow, | ||
383 | * but it will at least behave sensibly when they are | ||
384 | * in sequence. | ||
385 | */ | ||
386 | } else { | ||
387 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); | 388 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); |
388 | } | ||
389 | if (IS_ERR(pages)) | 389 | if (IS_ERR(pages)) |
390 | return PTR_ERR(pages); | 390 | return PTR_ERR(pages); |
391 | 391 | ||
392 | /* | ||
393 | * flush any page cache pages in this range. this | ||
394 | * will make concurrent normal and sync io slow, | ||
395 | * but it will at least behave sensibly when they are | ||
396 | * in sequence. | ||
397 | */ | ||
392 | ret = filemap_write_and_wait(inode->i_mapping); | 398 | ret = filemap_write_and_wait(inode->i_mapping); |
393 | if (ret < 0) | 399 | if (ret < 0) |
394 | goto done; | 400 | goto done; |
395 | 401 | ||
396 | ret = striped_read(inode, off, len, pages, num_pages, checkeof); | 402 | ret = striped_read(inode, off, len, pages, num_pages, checkeof, |
403 | file->f_flags & O_DIRECT); | ||
397 | 404 | ||
398 | if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) | 405 | if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) |
399 | ret = ceph_copy_page_vector_to_user(pages, data, off, ret); | 406 | ret = ceph_copy_page_vector_to_user(pages, data, off, ret); |
@@ -448,6 +455,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
448 | int flags; | 455 | int flags; |
449 | int do_sync = 0; | 456 | int do_sync = 0; |
450 | int check_caps = 0; | 457 | int check_caps = 0; |
458 | int page_align, io_align; | ||
451 | int ret; | 459 | int ret; |
452 | struct timespec mtime = CURRENT_TIME; | 460 | struct timespec mtime = CURRENT_TIME; |
453 | 461 | ||
@@ -462,6 +470,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
462 | else | 470 | else |
463 | pos = *offset; | 471 | pos = *offset; |
464 | 472 | ||
473 | io_align = pos & ~PAGE_MASK; | ||
474 | |||
465 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); | 475 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); |
466 | if (ret < 0) | 476 | if (ret < 0) |
467 | return ret; | 477 | return ret; |
@@ -486,20 +496,26 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
486 | */ | 496 | */ |
487 | more: | 497 | more: |
488 | len = left; | 498 | len = left; |
499 | if (file->f_flags & O_DIRECT) | ||
500 | /* write from beginning of first page, regardless of | ||
501 | io alignment */ | ||
502 | page_align = (pos - io_align) & ~PAGE_MASK; | ||
503 | else | ||
504 | page_align = pos & ~PAGE_MASK; | ||
489 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, | 505 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, |
490 | ceph_vino(inode), pos, &len, | 506 | ceph_vino(inode), pos, &len, |
491 | CEPH_OSD_OP_WRITE, flags, | 507 | CEPH_OSD_OP_WRITE, flags, |
492 | ci->i_snap_realm->cached_context, | 508 | ci->i_snap_realm->cached_context, |
493 | do_sync, | 509 | do_sync, |
494 | ci->i_truncate_seq, ci->i_truncate_size, | 510 | ci->i_truncate_seq, ci->i_truncate_size, |
495 | &mtime, false, 2); | 511 | &mtime, false, 2, page_align); |
496 | if (!req) | 512 | if (!req) |
497 | return -ENOMEM; | 513 | return -ENOMEM; |
498 | 514 | ||
499 | num_pages = calc_pages_for(pos, len); | 515 | num_pages = calc_pages_for(pos, len); |
500 | 516 | ||
501 | if (file->f_flags & O_DIRECT) { | 517 | if (file->f_flags & O_DIRECT) { |
502 | pages = ceph_get_direct_page_vector(data, num_pages, pos, len); | 518 | pages = ceph_get_direct_page_vector(data, num_pages); |
503 | if (IS_ERR(pages)) { | 519 | if (IS_ERR(pages)) { |
504 | ret = PTR_ERR(pages); | 520 | ret = PTR_ERR(pages); |
505 | goto out; | 521 | goto out; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 1d6a45b5a04c..bf1286588f26 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/fs.h> | 4 | #include <linux/fs.h> |
5 | #include <linux/smp_lock.h> | ||
6 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
7 | #include <linux/string.h> | 6 | #include <linux/string.h> |
8 | #include <linux/uaccess.h> | 7 | #include <linux/uaccess.h> |
@@ -471,7 +470,9 @@ void ceph_fill_file_time(struct inode *inode, int issued, | |||
471 | 470 | ||
472 | if (issued & (CEPH_CAP_FILE_EXCL| | 471 | if (issued & (CEPH_CAP_FILE_EXCL| |
473 | CEPH_CAP_FILE_WR| | 472 | CEPH_CAP_FILE_WR| |
474 | CEPH_CAP_FILE_BUFFER)) { | 473 | CEPH_CAP_FILE_BUFFER| |
474 | CEPH_CAP_AUTH_EXCL| | ||
475 | CEPH_CAP_XATTR_EXCL)) { | ||
475 | if (timespec_compare(ctime, &inode->i_ctime) > 0) { | 476 | if (timespec_compare(ctime, &inode->i_ctime) > 0) { |
476 | dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n", | 477 | dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n", |
477 | inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, | 478 | inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, |
@@ -511,7 +512,7 @@ void ceph_fill_file_time(struct inode *inode, int issued, | |||
511 | warn = 1; | 512 | warn = 1; |
512 | } | 513 | } |
513 | } else { | 514 | } else { |
514 | /* we have no write caps; whatever the MDS says is true */ | 515 | /* we have no write|excl caps; whatever the MDS says is true */ |
515 | if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) { | 516 | if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) { |
516 | inode->i_ctime = *ctime; | 517 | inode->i_ctime = *ctime; |
517 | inode->i_mtime = *mtime; | 518 | inode->i_mtime = *mtime; |
@@ -567,12 +568,17 @@ static int fill_inode(struct inode *inode, | |||
567 | 568 | ||
568 | /* | 569 | /* |
569 | * provided version will be odd if inode value is projected, | 570 | * provided version will be odd if inode value is projected, |
570 | * even if stable. skip the update if we have a newer info | 571 | * even if stable. skip the update if we have newer stable |
571 | * (e.g., due to inode info racing form multiple MDSs), or if | 572 | * info (ours>=theirs, e.g. due to racing mds replies), unless |
572 | * we are getting projected (unstable) inode info. | 573 | * we are getting projected (unstable) info (in which case the |
574 | * version is odd, and we want ours>theirs). | ||
575 | * us them | ||
576 | * 2 2 skip | ||
577 | * 3 2 skip | ||
578 | * 3 3 update | ||
573 | */ | 579 | */ |
574 | if (le64_to_cpu(info->version) > 0 && | 580 | if (le64_to_cpu(info->version) > 0 && |
575 | (ci->i_version & ~1) > le64_to_cpu(info->version)) | 581 | (ci->i_version & ~1) >= le64_to_cpu(info->version)) |
576 | goto no_change; | 582 | goto no_change; |
577 | 583 | ||
578 | issued = __ceph_caps_issued(ci, &implemented); | 584 | issued = __ceph_caps_issued(ci, &implemented); |
@@ -606,7 +612,14 @@ static int fill_inode(struct inode *inode, | |||
606 | le32_to_cpu(info->time_warp_seq), | 612 | le32_to_cpu(info->time_warp_seq), |
607 | &ctime, &mtime, &atime); | 613 | &ctime, &mtime, &atime); |
608 | 614 | ||
609 | ci->i_max_size = le64_to_cpu(info->max_size); | 615 | /* only update max_size on auth cap */ |
616 | if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) && | ||
617 | ci->i_max_size != le64_to_cpu(info->max_size)) { | ||
618 | dout("max_size %lld -> %llu\n", ci->i_max_size, | ||
619 | le64_to_cpu(info->max_size)); | ||
620 | ci->i_max_size = le64_to_cpu(info->max_size); | ||
621 | } | ||
622 | |||
610 | ci->i_layout = info->layout; | 623 | ci->i_layout = info->layout; |
611 | inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; | 624 | inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; |
612 | 625 | ||
@@ -1055,7 +1068,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1055 | ininfo = rinfo->targeti.in; | 1068 | ininfo = rinfo->targeti.in; |
1056 | vino.ino = le64_to_cpu(ininfo->ino); | 1069 | vino.ino = le64_to_cpu(ininfo->ino); |
1057 | vino.snap = le64_to_cpu(ininfo->snapid); | 1070 | vino.snap = le64_to_cpu(ininfo->snapid); |
1058 | if (!dn->d_inode) { | 1071 | in = dn->d_inode; |
1072 | if (!in) { | ||
1059 | in = ceph_get_inode(sb, vino); | 1073 | in = ceph_get_inode(sb, vino); |
1060 | if (IS_ERR(in)) { | 1074 | if (IS_ERR(in)) { |
1061 | pr_err("fill_trace bad get_inode " | 1075 | pr_err("fill_trace bad get_inode " |
@@ -1386,11 +1400,8 @@ static void ceph_invalidate_work(struct work_struct *work) | |||
1386 | spin_lock(&inode->i_lock); | 1400 | spin_lock(&inode->i_lock); |
1387 | dout("invalidate_pages %p gen %d revoking %d\n", inode, | 1401 | dout("invalidate_pages %p gen %d revoking %d\n", inode, |
1388 | ci->i_rdcache_gen, ci->i_rdcache_revoking); | 1402 | ci->i_rdcache_gen, ci->i_rdcache_revoking); |
1389 | if (ci->i_rdcache_gen == 0 || | 1403 | if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { |
1390 | ci->i_rdcache_revoking != ci->i_rdcache_gen) { | ||
1391 | BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen); | ||
1392 | /* nevermind! */ | 1404 | /* nevermind! */ |
1393 | ci->i_rdcache_revoking = 0; | ||
1394 | spin_unlock(&inode->i_lock); | 1405 | spin_unlock(&inode->i_lock); |
1395 | goto out; | 1406 | goto out; |
1396 | } | 1407 | } |
@@ -1400,15 +1411,16 @@ static void ceph_invalidate_work(struct work_struct *work) | |||
1400 | ceph_invalidate_nondirty_pages(inode->i_mapping); | 1411 | ceph_invalidate_nondirty_pages(inode->i_mapping); |
1401 | 1412 | ||
1402 | spin_lock(&inode->i_lock); | 1413 | spin_lock(&inode->i_lock); |
1403 | if (orig_gen == ci->i_rdcache_gen) { | 1414 | if (orig_gen == ci->i_rdcache_gen && |
1415 | orig_gen == ci->i_rdcache_revoking) { | ||
1404 | dout("invalidate_pages %p gen %d successful\n", inode, | 1416 | dout("invalidate_pages %p gen %d successful\n", inode, |
1405 | ci->i_rdcache_gen); | 1417 | ci->i_rdcache_gen); |
1406 | ci->i_rdcache_gen = 0; | 1418 | ci->i_rdcache_revoking--; |
1407 | ci->i_rdcache_revoking = 0; | ||
1408 | check = 1; | 1419 | check = 1; |
1409 | } else { | 1420 | } else { |
1410 | dout("invalidate_pages %p gen %d raced, gen now %d\n", | 1421 | dout("invalidate_pages %p gen %d raced, now %d revoking %d\n", |
1411 | inode, orig_gen, ci->i_rdcache_gen); | 1422 | inode, orig_gen, ci->i_rdcache_gen, |
1423 | ci->i_rdcache_revoking); | ||
1412 | } | 1424 | } |
1413 | spin_unlock(&inode->i_lock); | 1425 | spin_unlock(&inode->i_lock); |
1414 | 1426 | ||
@@ -1739,7 +1751,7 @@ int ceph_do_getattr(struct inode *inode, int mask) | |||
1739 | return 0; | 1751 | return 0; |
1740 | } | 1752 | } |
1741 | 1753 | ||
1742 | dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask)); | 1754 | dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode); |
1743 | if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) | 1755 | if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) |
1744 | return 0; | 1756 | return 0; |
1745 | 1757 | ||
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 3142b15940c2..098b18508479 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/debugfs.h> | 7 | #include <linux/debugfs.h> |
8 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
9 | #include <linux/smp_lock.h> | ||
10 | 9 | ||
11 | #include "super.h" | 10 | #include "super.h" |
12 | #include "mds_client.h" | 11 | #include "mds_client.h" |
@@ -529,6 +528,9 @@ static void __register_request(struct ceph_mds_client *mdsc, | |||
529 | ceph_mdsc_get_request(req); | 528 | ceph_mdsc_get_request(req); |
530 | __insert_request(mdsc, req); | 529 | __insert_request(mdsc, req); |
531 | 530 | ||
531 | req->r_uid = current_fsuid(); | ||
532 | req->r_gid = current_fsgid(); | ||
533 | |||
532 | if (dir) { | 534 | if (dir) { |
533 | struct ceph_inode_info *ci = ceph_inode(dir); | 535 | struct ceph_inode_info *ci = ceph_inode(dir); |
534 | 536 | ||
@@ -1588,8 +1590,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, | |||
1588 | 1590 | ||
1589 | head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch); | 1591 | head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch); |
1590 | head->op = cpu_to_le32(req->r_op); | 1592 | head->op = cpu_to_le32(req->r_op); |
1591 | head->caller_uid = cpu_to_le32(current_fsuid()); | 1593 | head->caller_uid = cpu_to_le32(req->r_uid); |
1592 | head->caller_gid = cpu_to_le32(current_fsgid()); | 1594 | head->caller_gid = cpu_to_le32(req->r_gid); |
1593 | head->args = req->r_args; | 1595 | head->args = req->r_args; |
1594 | 1596 | ||
1595 | ceph_encode_filepath(&p, end, ino1, path1); | 1597 | ceph_encode_filepath(&p, end, ino1, path1); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index d66d63c72355..9341fd4f1432 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -170,6 +170,8 @@ struct ceph_mds_request { | |||
170 | 170 | ||
171 | union ceph_mds_request_args r_args; | 171 | union ceph_mds_request_args r_args; |
172 | int r_fmode; /* file mode, if expecting cap */ | 172 | int r_fmode; /* file mode, if expecting cap */ |
173 | uid_t r_uid; | ||
174 | gid_t r_gid; | ||
173 | 175 | ||
174 | /* for choosing which mds to send this request to */ | 176 | /* for choosing which mds to send this request to */ |
175 | int r_direct_mode; | 177 | int r_direct_mode; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 1886294e12f7..7f01728a4657 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -293,9 +293,7 @@ struct ceph_inode_info { | |||
293 | int i_rd_ref, i_rdcache_ref, i_wr_ref; | 293 | int i_rd_ref, i_rdcache_ref, i_wr_ref; |
294 | int i_wrbuffer_ref, i_wrbuffer_ref_head; | 294 | int i_wrbuffer_ref, i_wrbuffer_ref_head; |
295 | u32 i_shared_gen; /* increment each time we get FILE_SHARED */ | 295 | u32 i_shared_gen; /* increment each time we get FILE_SHARED */ |
296 | u32 i_rdcache_gen; /* we increment this each time we get | 296 | u32 i_rdcache_gen; /* incremented each time we get FILE_CACHE. */ |
297 | FILE_CACHE. If it's non-zero, we | ||
298 | _may_ have cached pages. */ | ||
299 | u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */ | 297 | u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */ |
300 | 298 | ||
301 | struct list_head i_unsafe_writes; /* uncommitted sync writes */ | 299 | struct list_head i_unsafe_writes; /* uncommitted sync writes */ |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 410ed188faa1..a60579b007b0 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/compiler.h> | 19 | #include <linux/compiler.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/ioctl.h> | 22 | #include <linux/ioctl.h> |
24 | #include <linux/if.h> | 23 | #include <linux/if.h> |
25 | #include <linux/if_bridge.h> | 24 | #include <linux/if_bridge.h> |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 253732382d37..2720178b7718 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/key.h> | 28 | #include <linux/key.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/file.h> | 31 | #include <linux/file.h> |
33 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
34 | #include "ecryptfs_kernel.h" | 33 | #include "ecryptfs_kernel.h" |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2fedaf8b5012..acf8695fa8f0 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
29 | #include <linux/parser.h> | 29 | #include <linux/parser.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
32 | #include <linux/exportfs.h> | 31 | #include <linux/exportfs.h> |
33 | #include <linux/vfs.h> | 32 | #include <linux/vfs.h> |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bf5ae883b1bd..eb3bc2fe647e 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -331,6 +331,30 @@ mext_out: | |||
331 | return err; | 331 | return err; |
332 | } | 332 | } |
333 | 333 | ||
334 | case FITRIM: | ||
335 | { | ||
336 | struct super_block *sb = inode->i_sb; | ||
337 | struct fstrim_range range; | ||
338 | int ret = 0; | ||
339 | |||
340 | if (!capable(CAP_SYS_ADMIN)) | ||
341 | return -EPERM; | ||
342 | |||
343 | if (copy_from_user(&range, (struct fstrim_range *)arg, | ||
344 | sizeof(range))) | ||
345 | return -EFAULT; | ||
346 | |||
347 | ret = ext4_trim_fs(sb, &range); | ||
348 | if (ret < 0) | ||
349 | return ret; | ||
350 | |||
351 | if (copy_to_user((struct fstrim_range *)arg, &range, | ||
352 | sizeof(range))) | ||
353 | return -EFAULT; | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
334 | default: | 358 | default: |
335 | return -ENOTTY; | 359 | return -ENOTTY; |
336 | } | 360 | } |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 7f5451cd1d38..beacce11ac50 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -237,8 +237,6 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
237 | } while (bh != head); | 237 | } while (bh != head); |
238 | } | 238 | } |
239 | 239 | ||
240 | put_io_page(io_end->pages[i]); | ||
241 | |||
242 | /* | 240 | /* |
243 | * If this is a partial write which happened to make | 241 | * If this is a partial write which happened to make |
244 | * all buffers uptodate then we can optimize away a | 242 | * all buffers uptodate then we can optimize away a |
@@ -248,6 +246,8 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
248 | */ | 246 | */ |
249 | if (!partial_write) | 247 | if (!partial_write) |
250 | SetPageUptodate(page); | 248 | SetPageUptodate(page); |
249 | |||
250 | put_io_page(io_end->pages[i]); | ||
251 | } | 251 | } |
252 | io_end->num_io_pages = 0; | 252 | io_end->num_io_pages = 0; |
253 | inode = io_end->inode; | 253 | inode = io_end->inode; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 61182fe6254e..e32195d6aac3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1197,7 +1197,6 @@ static const struct super_operations ext4_sops = { | |||
1197 | .quota_write = ext4_quota_write, | 1197 | .quota_write = ext4_quota_write, |
1198 | #endif | 1198 | #endif |
1199 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1199 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1200 | .trim_fs = ext4_trim_fs | ||
1201 | }; | 1200 | }; |
1202 | 1201 | ||
1203 | static const struct super_operations ext4_nojournal_sops = { | 1202 | static const struct super_operations ext4_nojournal_sops = { |
@@ -2799,9 +2798,6 @@ static void ext4_clear_request_list(void) | |||
2799 | struct ext4_li_request *elr; | 2798 | struct ext4_li_request *elr; |
2800 | 2799 | ||
2801 | mutex_lock(&ext4_li_info->li_list_mtx); | 2800 | mutex_lock(&ext4_li_info->li_list_mtx); |
2802 | if (list_empty(&ext4_li_info->li_request_list)) | ||
2803 | return; | ||
2804 | |||
2805 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { | 2801 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { |
2806 | elr = list_entry(pos, struct ext4_li_request, | 2802 | elr = list_entry(pos, struct ext4_li_request, |
2807 | lr_request); | 2803 | lr_request); |
@@ -3268,13 +3264,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3268 | * Test whether we have more sectors than will fit in sector_t, | 3264 | * Test whether we have more sectors than will fit in sector_t, |
3269 | * and whether the max offset is addressable by the page cache. | 3265 | * and whether the max offset is addressable by the page cache. |
3270 | */ | 3266 | */ |
3271 | ret = generic_check_addressable(sb->s_blocksize_bits, | 3267 | err = generic_check_addressable(sb->s_blocksize_bits, |
3272 | ext4_blocks_count(es)); | 3268 | ext4_blocks_count(es)); |
3273 | if (ret) { | 3269 | if (err) { |
3274 | ext4_msg(sb, KERN_ERR, "filesystem" | 3270 | ext4_msg(sb, KERN_ERR, "filesystem" |
3275 | " too large to mount safely on this system"); | 3271 | " too large to mount safely on this system"); |
3276 | if (sizeof(sector_t) < 8) | 3272 | if (sizeof(sector_t) < 8) |
3277 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); | 3273 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); |
3274 | ret = err; | ||
3278 | goto failed_mount; | 3275 | goto failed_mount; |
3279 | } | 3276 | } |
3280 | 3277 | ||
diff --git a/fs/ioctl.c b/fs/ioctl.c index e92fdbb3bc3a..d6cc16476620 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | #include <linux/syscalls.h> | 7 | #include <linux/syscalls.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/smp_lock.h> | ||
10 | #include <linux/capability.h> | 9 | #include <linux/capability.h> |
11 | #include <linux/file.h> | 10 | #include <linux/file.h> |
12 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
@@ -530,41 +529,6 @@ static int ioctl_fsthaw(struct file *filp) | |||
530 | return thaw_super(sb); | 529 | return thaw_super(sb); |
531 | } | 530 | } |
532 | 531 | ||
533 | static int ioctl_fstrim(struct file *filp, void __user *argp) | ||
534 | { | ||
535 | struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; | ||
536 | struct fstrim_range range; | ||
537 | int ret = 0; | ||
538 | |||
539 | if (!capable(CAP_SYS_ADMIN)) | ||
540 | return -EPERM; | ||
541 | |||
542 | /* If filesystem doesn't support trim feature, return. */ | ||
543 | if (sb->s_op->trim_fs == NULL) | ||
544 | return -EOPNOTSUPP; | ||
545 | |||
546 | /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */ | ||
547 | if (sb->s_bdev == NULL) | ||
548 | return -EINVAL; | ||
549 | |||
550 | if (argp == NULL) { | ||
551 | range.start = 0; | ||
552 | range.len = ULLONG_MAX; | ||
553 | range.minlen = 0; | ||
554 | } else if (copy_from_user(&range, argp, sizeof(range))) | ||
555 | return -EFAULT; | ||
556 | |||
557 | ret = sb->s_op->trim_fs(sb, &range); | ||
558 | if (ret < 0) | ||
559 | return ret; | ||
560 | |||
561 | if ((argp != NULL) && | ||
562 | (copy_to_user(argp, &range, sizeof(range)))) | ||
563 | return -EFAULT; | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /* | 532 | /* |
569 | * When you add any new common ioctls to the switches above and below | 533 | * When you add any new common ioctls to the switches above and below |
570 | * please update compat_sys_ioctl() too. | 534 | * please update compat_sys_ioctl() too. |
@@ -615,10 +579,6 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, | |||
615 | error = ioctl_fsthaw(filp); | 579 | error = ioctl_fsthaw(filp); |
616 | break; | 580 | break; |
617 | 581 | ||
618 | case FITRIM: | ||
619 | error = ioctl_fstrim(filp, argp); | ||
620 | break; | ||
621 | |||
622 | case FS_IOC_FIEMAP: | 582 | case FS_IOC_FIEMAP: |
623 | return ioctl_fiemap(filp, arg); | 583 | return ioctl_fiemap(filp, arg); |
624 | 584 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index c590d155c095..f837ba953529 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -899,6 +899,14 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
899 | 899 | ||
900 | /* journal descriptor can store up to n blocks -bzzz */ | 900 | /* journal descriptor can store up to n blocks -bzzz */ |
901 | journal->j_blocksize = blocksize; | 901 | journal->j_blocksize = blocksize; |
902 | journal->j_dev = bdev; | ||
903 | journal->j_fs_dev = fs_dev; | ||
904 | journal->j_blk_offset = start; | ||
905 | journal->j_maxlen = len; | ||
906 | bdevname(journal->j_dev, journal->j_devname); | ||
907 | p = journal->j_devname; | ||
908 | while ((p = strchr(p, '/'))) | ||
909 | *p = '!'; | ||
902 | jbd2_stats_proc_init(journal); | 910 | jbd2_stats_proc_init(journal); |
903 | n = journal->j_blocksize / sizeof(journal_block_tag_t); | 911 | n = journal->j_blocksize / sizeof(journal_block_tag_t); |
904 | journal->j_wbufsize = n; | 912 | journal->j_wbufsize = n; |
@@ -908,14 +916,6 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
908 | __func__); | 916 | __func__); |
909 | goto out_err; | 917 | goto out_err; |
910 | } | 918 | } |
911 | journal->j_dev = bdev; | ||
912 | journal->j_fs_dev = fs_dev; | ||
913 | journal->j_blk_offset = start; | ||
914 | journal->j_maxlen = len; | ||
915 | bdevname(journal->j_dev, journal->j_devname); | ||
916 | p = journal->j_devname; | ||
917 | while ((p = strchr(p, '/'))) | ||
918 | *p = '!'; | ||
919 | 919 | ||
920 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); | 920 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); |
921 | if (!bh) { | 921 | if (!bh) { |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index d5bb86866e6c..25509eb28fd7 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
15 | #include <linux/sunrpc/svc.h> | 15 | #include <linux/sunrpc/svc.h> |
16 | #include <linux/lockd/lockd.h> | 16 | #include <linux/lockd/lockd.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/kthread.h> | 17 | #include <linux/kthread.h> |
19 | 18 | ||
20 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 19 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 47ea1e1925b8..332c54cf75e0 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -7,7 +7,6 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/smp_lock.h> | ||
11 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
12 | #include <linux/types.h> | 11 | #include <linux/types.h> |
13 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 25e21e4023b2..ed0c59fe23ce 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -124,7 +124,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) | |||
124 | continue; | 124 | continue; |
125 | if (host->h_server != ni->server) | 125 | if (host->h_server != ni->server) |
126 | continue; | 126 | continue; |
127 | if (ni->server && | 127 | if (ni->server && ni->src_len != 0 && |
128 | !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap)) | 128 | !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap)) |
129 | continue; | 129 | continue; |
130 | 130 | ||
@@ -167,6 +167,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) | |||
167 | host->h_addrlen = ni->salen; | 167 | host->h_addrlen = ni->salen; |
168 | rpc_set_port(nlm_addr(host), 0); | 168 | rpc_set_port(nlm_addr(host), 0); |
169 | memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); | 169 | memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); |
170 | host->h_srcaddrlen = ni->src_len; | ||
170 | host->h_version = ni->version; | 171 | host->h_version = ni->version; |
171 | host->h_proto = ni->protocol; | 172 | host->h_proto = ni->protocol; |
172 | host->h_rpcclnt = NULL; | 173 | host->h_rpcclnt = NULL; |
@@ -238,9 +239,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
238 | const char *hostname, | 239 | const char *hostname, |
239 | int noresvport) | 240 | int noresvport) |
240 | { | 241 | { |
241 | const struct sockaddr source = { | ||
242 | .sa_family = AF_UNSPEC, | ||
243 | }; | ||
244 | struct nlm_lookup_host_info ni = { | 242 | struct nlm_lookup_host_info ni = { |
245 | .server = 0, | 243 | .server = 0, |
246 | .sap = sap, | 244 | .sap = sap, |
@@ -249,8 +247,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
249 | .version = version, | 247 | .version = version, |
250 | .hostname = hostname, | 248 | .hostname = hostname, |
251 | .hostname_len = strlen(hostname), | 249 | .hostname_len = strlen(hostname), |
252 | .src_sap = &source, | ||
253 | .src_len = sizeof(source), | ||
254 | .noresvport = noresvport, | 250 | .noresvport = noresvport, |
255 | }; | 251 | }; |
256 | 252 | ||
@@ -357,7 +353,6 @@ nlm_bind_host(struct nlm_host *host) | |||
357 | .protocol = host->h_proto, | 353 | .protocol = host->h_proto, |
358 | .address = nlm_addr(host), | 354 | .address = nlm_addr(host), |
359 | .addrsize = host->h_addrlen, | 355 | .addrsize = host->h_addrlen, |
360 | .saddress = nlm_srcaddr(host), | ||
361 | .timeout = &timeparms, | 356 | .timeout = &timeparms, |
362 | .servername = host->h_name, | 357 | .servername = host->h_name, |
363 | .program = &nlm_program, | 358 | .program = &nlm_program, |
@@ -376,6 +371,8 @@ nlm_bind_host(struct nlm_host *host) | |||
376 | args.flags |= RPC_CLNT_CREATE_HARDRTRY; | 371 | args.flags |= RPC_CLNT_CREATE_HARDRTRY; |
377 | if (host->h_noresvport) | 372 | if (host->h_noresvport) |
378 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; | 373 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; |
374 | if (host->h_srcaddrlen) | ||
375 | args.saddress = nlm_srcaddr(host); | ||
379 | 376 | ||
380 | clnt = rpc_create(&args); | 377 | clnt = rpc_create(&args); |
381 | if (!IS_ERR(clnt)) | 378 | if (!IS_ERR(clnt)) |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index a336e832475d..38d261192453 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
14 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
15 | 14 | ||
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index c462d346acbd..ef5659b211e9 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/sunrpc/clnt.h> | 28 | #include <linux/sunrpc/clnt.h> |
30 | #include <linux/sunrpc/svc.h> | 29 | #include <linux/sunrpc/svc.h> |
31 | #include <linux/lockd/nlm.h> | 30 | #include <linux/lockd/nlm.h> |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index c3069f38d602..0caea5310ac3 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
14 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
15 | 14 | ||
diff --git a/fs/locks.c b/fs/locks.c index 0e62dd35d088..8729347bcd1a 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -122,7 +122,6 @@ | |||
122 | #include <linux/module.h> | 122 | #include <linux/module.h> |
123 | #include <linux/security.h> | 123 | #include <linux/security.h> |
124 | #include <linux/slab.h> | 124 | #include <linux/slab.h> |
125 | #include <linux/smp_lock.h> | ||
126 | #include <linux/syscalls.h> | 125 | #include <linux/syscalls.h> |
127 | #include <linux/time.h> | 126 | #include <linux/time.h> |
128 | #include <linux/rcupdate.h> | 127 | #include <linux/rcupdate.h> |
diff --git a/fs/namespace.c b/fs/namespace.c index 8a415c9c5e55..3dbfc072ec70 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/percpu.h> | 15 | #include <linux/percpu.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/acct.h> | 18 | #include <linux/acct.h> |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index aac8832e919e..f22b12e7d337 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
22 | #include <linux/smp_lock.h> | ||
23 | 22 | ||
24 | #include <linux/ncp_fs.h> | 23 | #include <linux/ncp_fs.h> |
25 | 24 | ||
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 6c754f70c529..cb50aaf981df 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/smp_lock.h> | ||
21 | 20 | ||
22 | #include <linux/ncp_fs.h> | 21 | #include <linux/ncp_fs.h> |
23 | #include "ncplib_kernel.h" | 22 | #include "ncplib_kernel.h" |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index d290545aa0c4..8fb93b604e73 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/vfs.h> | 29 | #include <linux/vfs.h> |
31 | #include <linux/mount.h> | 30 | #include <linux/mount.h> |
32 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index c2a1f9a155c3..d40a547e3377 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/mount.h> | 17 | #include <linux/mount.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/highuid.h> | 19 | #include <linux/highuid.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
22 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
23 | 22 | ||
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index aeec017fe814..93a8b3bd69e3 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/completion.h> | 9 | #include <linux/completion.h> |
10 | #include <linux/ip.h> | 10 | #include <linux/ip.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/sunrpc/svc.h> | 12 | #include <linux/sunrpc/svc.h> |
14 | #include <linux/sunrpc/svcsock.h> | 13 | #include <linux/sunrpc/svcsock.h> |
15 | #include <linux/nfs_fs.h> | 14 | #include <linux/nfs_fs.h> |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 232a7eead33a..1fd62fc49be3 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
16 | 15 | ||
17 | #include <linux/nfs4.h> | 16 | #include <linux/nfs4.h> |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 07ac3847e562..662df2a5fad5 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/kmemleak.h> | ||
37 | 38 | ||
38 | #include "delegation.h" | 39 | #include "delegation.h" |
39 | #include "iostat.h" | 40 | #include "iostat.h" |
@@ -194,9 +195,13 @@ typedef struct { | |||
194 | static | 195 | static |
195 | struct nfs_cache_array *nfs_readdir_get_array(struct page *page) | 196 | struct nfs_cache_array *nfs_readdir_get_array(struct page *page) |
196 | { | 197 | { |
198 | void *ptr; | ||
197 | if (page == NULL) | 199 | if (page == NULL) |
198 | return ERR_PTR(-EIO); | 200 | return ERR_PTR(-EIO); |
199 | return (struct nfs_cache_array *)kmap(page); | 201 | ptr = kmap(page); |
202 | if (ptr == NULL) | ||
203 | return ERR_PTR(-ENOMEM); | ||
204 | return ptr; | ||
200 | } | 205 | } |
201 | 206 | ||
202 | static | 207 | static |
@@ -213,6 +218,9 @@ int nfs_readdir_clear_array(struct page *page, gfp_t mask) | |||
213 | { | 218 | { |
214 | struct nfs_cache_array *array = nfs_readdir_get_array(page); | 219 | struct nfs_cache_array *array = nfs_readdir_get_array(page); |
215 | int i; | 220 | int i; |
221 | |||
222 | if (IS_ERR(array)) | ||
223 | return PTR_ERR(array); | ||
216 | for (i = 0; i < array->size; i++) | 224 | for (i = 0; i < array->size; i++) |
217 | kfree(array->array[i].string.name); | 225 | kfree(array->array[i].string.name); |
218 | nfs_readdir_release_array(page); | 226 | nfs_readdir_release_array(page); |
@@ -231,6 +239,11 @@ int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int le | |||
231 | string->name = kmemdup(name, len, GFP_KERNEL); | 239 | string->name = kmemdup(name, len, GFP_KERNEL); |
232 | if (string->name == NULL) | 240 | if (string->name == NULL) |
233 | return -ENOMEM; | 241 | return -ENOMEM; |
242 | /* | ||
243 | * Avoid a kmemleak false positive. The pointer to the name is stored | ||
244 | * in a page cache page which kmemleak does not scan. | ||
245 | */ | ||
246 | kmemleak_not_leak(string->name); | ||
234 | string->hash = full_name_hash(name, len); | 247 | string->hash = full_name_hash(name, len); |
235 | return 0; | 248 | return 0; |
236 | } | 249 | } |
@@ -244,7 +257,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) | |||
244 | 257 | ||
245 | if (IS_ERR(array)) | 258 | if (IS_ERR(array)) |
246 | return PTR_ERR(array); | 259 | return PTR_ERR(array); |
247 | ret = -EIO; | 260 | ret = -ENOSPC; |
248 | if (array->size >= MAX_READDIR_ARRAY) | 261 | if (array->size >= MAX_READDIR_ARRAY) |
249 | goto out; | 262 | goto out; |
250 | 263 | ||
@@ -255,9 +268,9 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) | |||
255 | if (ret) | 268 | if (ret) |
256 | goto out; | 269 | goto out; |
257 | array->last_cookie = entry->cookie; | 270 | array->last_cookie = entry->cookie; |
271 | array->size++; | ||
258 | if (entry->eof == 1) | 272 | if (entry->eof == 1) |
259 | array->eof_index = array->size; | 273 | array->eof_index = array->size; |
260 | array->size++; | ||
261 | out: | 274 | out: |
262 | nfs_readdir_release_array(page); | 275 | nfs_readdir_release_array(page); |
263 | return ret; | 276 | return ret; |
@@ -272,7 +285,7 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri | |||
272 | if (diff < 0) | 285 | if (diff < 0) |
273 | goto out_eof; | 286 | goto out_eof; |
274 | if (diff >= array->size) { | 287 | if (diff >= array->size) { |
275 | if (array->eof_index > 0) | 288 | if (array->eof_index >= 0) |
276 | goto out_eof; | 289 | goto out_eof; |
277 | desc->current_index += array->size; | 290 | desc->current_index += array->size; |
278 | return -EAGAIN; | 291 | return -EAGAIN; |
@@ -281,8 +294,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri | |||
281 | index = (unsigned int)diff; | 294 | index = (unsigned int)diff; |
282 | *desc->dir_cookie = array->array[index].cookie; | 295 | *desc->dir_cookie = array->array[index].cookie; |
283 | desc->cache_entry_index = index; | 296 | desc->cache_entry_index = index; |
284 | if (index == array->eof_index) | ||
285 | desc->eof = 1; | ||
286 | return 0; | 297 | return 0; |
287 | out_eof: | 298 | out_eof: |
288 | desc->eof = 1; | 299 | desc->eof = 1; |
@@ -296,17 +307,17 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des | |||
296 | int status = -EAGAIN; | 307 | int status = -EAGAIN; |
297 | 308 | ||
298 | for (i = 0; i < array->size; i++) { | 309 | for (i = 0; i < array->size; i++) { |
299 | if (i == array->eof_index) { | ||
300 | desc->eof = 1; | ||
301 | status = -EBADCOOKIE; | ||
302 | } | ||
303 | if (array->array[i].cookie == *desc->dir_cookie) { | 310 | if (array->array[i].cookie == *desc->dir_cookie) { |
304 | desc->cache_entry_index = i; | 311 | desc->cache_entry_index = i; |
305 | status = 0; | 312 | status = 0; |
306 | break; | 313 | goto out; |
307 | } | 314 | } |
308 | } | 315 | } |
309 | 316 | if (i == array->eof_index) { | |
317 | desc->eof = 1; | ||
318 | status = -EBADCOOKIE; | ||
319 | } | ||
320 | out: | ||
310 | return status; | 321 | return status; |
311 | } | 322 | } |
312 | 323 | ||
@@ -449,7 +460,7 @@ out: | |||
449 | 460 | ||
450 | /* Perform conversion from xdr to cache array */ | 461 | /* Perform conversion from xdr to cache array */ |
451 | static | 462 | static |
452 | void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, | 463 | int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, |
453 | void *xdr_page, struct page *page, unsigned int buflen) | 464 | void *xdr_page, struct page *page, unsigned int buflen) |
454 | { | 465 | { |
455 | struct xdr_stream stream; | 466 | struct xdr_stream stream; |
@@ -471,21 +482,29 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e | |||
471 | 482 | ||
472 | do { | 483 | do { |
473 | status = xdr_decode(desc, entry, &stream); | 484 | status = xdr_decode(desc, entry, &stream); |
474 | if (status != 0) | 485 | if (status != 0) { |
486 | if (status == -EAGAIN) | ||
487 | status = 0; | ||
475 | break; | 488 | break; |
489 | } | ||
476 | 490 | ||
477 | if (nfs_readdir_add_to_array(entry, page) == -1) | ||
478 | break; | ||
479 | if (desc->plus == 1) | 491 | if (desc->plus == 1) |
480 | nfs_prime_dcache(desc->file->f_path.dentry, entry); | 492 | nfs_prime_dcache(desc->file->f_path.dentry, entry); |
493 | |||
494 | status = nfs_readdir_add_to_array(entry, page); | ||
495 | if (status != 0) | ||
496 | break; | ||
481 | } while (!entry->eof); | 497 | } while (!entry->eof); |
482 | 498 | ||
483 | if (status == -EBADCOOKIE && entry->eof) { | 499 | if (status == -EBADCOOKIE && entry->eof) { |
484 | array = nfs_readdir_get_array(page); | 500 | array = nfs_readdir_get_array(page); |
485 | array->eof_index = array->size - 1; | 501 | if (!IS_ERR(array)) { |
486 | status = 0; | 502 | array->eof_index = array->size; |
487 | nfs_readdir_release_array(page); | 503 | status = 0; |
504 | nfs_readdir_release_array(page); | ||
505 | } | ||
488 | } | 506 | } |
507 | return status; | ||
489 | } | 508 | } |
490 | 509 | ||
491 | static | 510 | static |
@@ -537,7 +556,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
537 | struct nfs_entry entry; | 556 | struct nfs_entry entry; |
538 | struct file *file = desc->file; | 557 | struct file *file = desc->file; |
539 | struct nfs_cache_array *array; | 558 | struct nfs_cache_array *array; |
540 | int status = 0; | 559 | int status = -ENOMEM; |
541 | unsigned int array_size = ARRAY_SIZE(pages); | 560 | unsigned int array_size = ARRAY_SIZE(pages); |
542 | 561 | ||
543 | entry.prev_cookie = 0; | 562 | entry.prev_cookie = 0; |
@@ -549,6 +568,10 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
549 | goto out; | 568 | goto out; |
550 | 569 | ||
551 | array = nfs_readdir_get_array(page); | 570 | array = nfs_readdir_get_array(page); |
571 | if (IS_ERR(array)) { | ||
572 | status = PTR_ERR(array); | ||
573 | goto out; | ||
574 | } | ||
552 | memset(array, 0, sizeof(struct nfs_cache_array)); | 575 | memset(array, 0, sizeof(struct nfs_cache_array)); |
553 | array->eof_index = -1; | 576 | array->eof_index = -1; |
554 | 577 | ||
@@ -556,12 +579,19 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
556 | if (!pages_ptr) | 579 | if (!pages_ptr) |
557 | goto out_release_array; | 580 | goto out_release_array; |
558 | do { | 581 | do { |
582 | unsigned int pglen; | ||
559 | status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); | 583 | status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); |
560 | 584 | ||
561 | if (status < 0) | 585 | if (status < 0) |
562 | break; | 586 | break; |
563 | nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE); | 587 | pglen = status; |
564 | } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY); | 588 | status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); |
589 | if (status < 0) { | ||
590 | if (status == -ENOSPC) | ||
591 | status = 0; | ||
592 | break; | ||
593 | } | ||
594 | } while (array->eof_index < 0); | ||
565 | 595 | ||
566 | nfs_readdir_free_large_page(pages_ptr, pages, array_size); | 596 | nfs_readdir_free_large_page(pages_ptr, pages, array_size); |
567 | out_release_array: | 597 | out_release_array: |
@@ -582,8 +612,10 @@ static | |||
582 | int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) | 612 | int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) |
583 | { | 613 | { |
584 | struct inode *inode = desc->file->f_path.dentry->d_inode; | 614 | struct inode *inode = desc->file->f_path.dentry->d_inode; |
615 | int ret; | ||
585 | 616 | ||
586 | if (nfs_readdir_xdr_to_array(desc, page, inode) < 0) | 617 | ret = nfs_readdir_xdr_to_array(desc, page, inode); |
618 | if (ret < 0) | ||
587 | goto error; | 619 | goto error; |
588 | SetPageUptodate(page); | 620 | SetPageUptodate(page); |
589 | 621 | ||
@@ -595,7 +627,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) | |||
595 | return 0; | 627 | return 0; |
596 | error: | 628 | error: |
597 | unlock_page(page); | 629 | unlock_page(page); |
598 | return -EIO; | 630 | return ret; |
599 | } | 631 | } |
600 | 632 | ||
601 | static | 633 | static |
@@ -608,12 +640,8 @@ void cache_page_release(nfs_readdir_descriptor_t *desc) | |||
608 | static | 640 | static |
609 | struct page *get_cache_page(nfs_readdir_descriptor_t *desc) | 641 | struct page *get_cache_page(nfs_readdir_descriptor_t *desc) |
610 | { | 642 | { |
611 | struct page *page; | 643 | return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, |
612 | page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, | ||
613 | desc->page_index, (filler_t *)nfs_readdir_filler, desc); | 644 | desc->page_index, (filler_t *)nfs_readdir_filler, desc); |
614 | if (IS_ERR(page)) | ||
615 | desc->eof = 1; | ||
616 | return page; | ||
617 | } | 645 | } |
618 | 646 | ||
619 | /* | 647 | /* |
@@ -639,8 +667,10 @@ int find_cache_page(nfs_readdir_descriptor_t *desc) | |||
639 | static inline | 667 | static inline |
640 | int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) | 668 | int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) |
641 | { | 669 | { |
642 | int res = -EAGAIN; | 670 | int res; |
643 | 671 | ||
672 | if (desc->page_index == 0) | ||
673 | desc->current_index = 0; | ||
644 | while (1) { | 674 | while (1) { |
645 | res = find_cache_page(desc); | 675 | res = find_cache_page(desc); |
646 | if (res != -EAGAIN) | 676 | if (res != -EAGAIN) |
@@ -670,6 +700,8 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
670 | struct dentry *dentry = NULL; | 700 | struct dentry *dentry = NULL; |
671 | 701 | ||
672 | array = nfs_readdir_get_array(desc->page); | 702 | array = nfs_readdir_get_array(desc->page); |
703 | if (IS_ERR(array)) | ||
704 | return PTR_ERR(array); | ||
673 | 705 | ||
674 | for (i = desc->cache_entry_index; i < array->size; i++) { | 706 | for (i = desc->cache_entry_index; i < array->size; i++) { |
675 | d_type = DT_UNKNOWN; | 707 | d_type = DT_UNKNOWN; |
@@ -685,11 +717,9 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
685 | *desc->dir_cookie = array->array[i+1].cookie; | 717 | *desc->dir_cookie = array->array[i+1].cookie; |
686 | else | 718 | else |
687 | *desc->dir_cookie = array->last_cookie; | 719 | *desc->dir_cookie = array->last_cookie; |
688 | if (i == array->eof_index) { | ||
689 | desc->eof = 1; | ||
690 | break; | ||
691 | } | ||
692 | } | 720 | } |
721 | if (i == array->eof_index) | ||
722 | desc->eof = 1; | ||
693 | 723 | ||
694 | nfs_readdir_release_array(desc->page); | 724 | nfs_readdir_release_array(desc->page); |
695 | cache_page_release(desc); | 725 | cache_page_release(desc); |
@@ -1345,12 +1375,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1345 | res = NULL; | 1375 | res = NULL; |
1346 | goto out; | 1376 | goto out; |
1347 | /* This turned out not to be a regular file */ | 1377 | /* This turned out not to be a regular file */ |
1348 | case -EISDIR: | ||
1349 | case -ENOTDIR: | 1378 | case -ENOTDIR: |
1350 | goto no_open; | 1379 | goto no_open; |
1351 | case -ELOOP: | 1380 | case -ELOOP: |
1352 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | 1381 | if (!(nd->intent.open.flags & O_NOFOLLOW)) |
1353 | goto no_open; | 1382 | goto no_open; |
1383 | /* case -EISDIR: */ | ||
1354 | /* case -EINVAL: */ | 1384 | /* case -EINVAL: */ |
1355 | default: | 1385 | default: |
1356 | res = ERR_CAST(inode); | 1386 | res = ERR_CAST(inode); |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index e6bf45710cc7..2563f765c9b4 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
423 | struct page **page; | 423 | struct page **page; |
424 | size_t hdrlen; | 424 | size_t hdrlen; |
425 | unsigned int pglen, recvd; | 425 | unsigned int pglen, recvd; |
426 | int status, nr = 0; | 426 | int status; |
427 | 427 | ||
428 | if ((status = ntohl(*p++))) | 428 | if ((status = ntohl(*p++))) |
429 | return nfs_stat_to_errno(status); | 429 | return nfs_stat_to_errno(status); |
@@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
443 | if (pglen > recvd) | 443 | if (pglen > recvd) |
444 | pglen = recvd; | 444 | pglen = recvd; |
445 | page = rcvbuf->pages; | 445 | page = rcvbuf->pages; |
446 | return nr; | 446 | return pglen; |
447 | } | 447 | } |
448 | 448 | ||
449 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 449 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index d9a5e832c257..748dc91a4a14 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res | |||
555 | struct page **page; | 555 | struct page **page; |
556 | size_t hdrlen; | 556 | size_t hdrlen; |
557 | u32 recvd, pglen; | 557 | u32 recvd, pglen; |
558 | int status, nr = 0; | 558 | int status; |
559 | 559 | ||
560 | status = ntohl(*p++); | 560 | status = ntohl(*p++); |
561 | /* Decode post_op_attrs */ | 561 | /* Decode post_op_attrs */ |
@@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res | |||
586 | pglen = recvd; | 586 | pglen = recvd; |
587 | page = rcvbuf->pages; | 587 | page = rcvbuf->pages; |
588 | 588 | ||
589 | return nr; | 589 | return pglen; |
590 | } | 590 | } |
591 | 591 | ||
592 | __be32 * | 592 | __be32 * |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0f24cdf2cb13..6a653ffd8e4e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2852,8 +2852,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2852 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 2852 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); |
2853 | res.pgbase = args.pgbase; | 2853 | res.pgbase = args.pgbase; |
2854 | status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); | 2854 | status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); |
2855 | if (status == 0) | 2855 | if (status >= 0) { |
2856 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 2856 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); |
2857 | status += args.pgbase; | ||
2858 | } | ||
2857 | 2859 | ||
2858 | nfs_invalidate_atime(dir); | 2860 | nfs_invalidate_atime(dir); |
2859 | 2861 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f313c4cce7e4..b7a204ff6fe1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n | |||
4518 | xdr_read_pages(xdr, pglen); | 4518 | xdr_read_pages(xdr, pglen); |
4519 | 4519 | ||
4520 | 4520 | ||
4521 | return 0; | 4521 | return pglen; |
4522 | } | 4522 | } |
4523 | 4523 | ||
4524 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | 4524 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 0a42e8f4adcb..3c045044fca2 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/nfs_mount.h> | 39 | #include <linux/nfs_mount.h> |
40 | #include <linux/nfs4_mount.h> | 40 | #include <linux/nfs4_mount.h> |
41 | #include <linux/lockd/bind.h> | 41 | #include <linux/lockd/bind.h> |
42 | #include <linux/smp_lock.h> | ||
43 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
44 | #include <linux/mount.h> | 43 | #include <linux/mount.h> |
45 | #include <linux/mnt_namespace.h> | 44 | #include <linux/mnt_namespace.h> |
@@ -67,6 +66,12 @@ | |||
67 | 66 | ||
68 | #define NFSDBG_FACILITY NFSDBG_VFS | 67 | #define NFSDBG_FACILITY NFSDBG_VFS |
69 | 68 | ||
69 | #ifdef CONFIG_NFS_V3 | ||
70 | #define NFS_DEFAULT_VERSION 3 | ||
71 | #else | ||
72 | #define NFS_DEFAULT_VERSION 2 | ||
73 | #endif | ||
74 | |||
70 | enum { | 75 | enum { |
71 | /* Mount options that take no arguments */ | 76 | /* Mount options that take no arguments */ |
72 | Opt_soft, Opt_hard, | 77 | Opt_soft, Opt_hard, |
@@ -2277,7 +2282,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2277 | }; | 2282 | }; |
2278 | int error = -ENOMEM; | 2283 | int error = -ENOMEM; |
2279 | 2284 | ||
2280 | data = nfs_alloc_parsed_mount_data(3); | 2285 | data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); |
2281 | mntfh = nfs_alloc_fhandle(); | 2286 | mntfh = nfs_alloc_fhandle(); |
2282 | if (data == NULL || mntfh == NULL) | 2287 | if (data == NULL || mntfh == NULL) |
2283 | goto out_free_fh; | 2288 | goto out_free_fh; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ad2bfa68d534..116cab970e0f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2262,7 +2262,7 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access) | |||
2262 | * Spawn a thread to perform a recall on the delegation represented | 2262 | * Spawn a thread to perform a recall on the delegation represented |
2263 | * by the lease (file_lock) | 2263 | * by the lease (file_lock) |
2264 | * | 2264 | * |
2265 | * Called from break_lease() with lock_kernel() held. | 2265 | * Called from break_lease() with lock_flocks() held. |
2266 | * Note: we assume break_lease will only call this *once* for any given | 2266 | * Note: we assume break_lease will only call this *once* for any given |
2267 | * lease. | 2267 | * lease. |
2268 | */ | 2268 | */ |
@@ -2286,7 +2286,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl) | |||
2286 | list_add_tail(&dp->dl_recall_lru, &del_recall_lru); | 2286 | list_add_tail(&dp->dl_recall_lru, &del_recall_lru); |
2287 | spin_unlock(&recall_lock); | 2287 | spin_unlock(&recall_lock); |
2288 | 2288 | ||
2289 | /* only place dl_time is set. protected by lock_kernel*/ | 2289 | /* only place dl_time is set. protected by lock_flocks*/ |
2290 | dp->dl_time = get_seconds(); | 2290 | dp->dl_time = get_seconds(); |
2291 | 2291 | ||
2292 | /* | 2292 | /* |
@@ -2303,7 +2303,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl) | |||
2303 | /* | 2303 | /* |
2304 | * The file_lock is being reapd. | 2304 | * The file_lock is being reapd. |
2305 | * | 2305 | * |
2306 | * Called by locks_free_lock() with lock_kernel() held. | 2306 | * Called by locks_free_lock() with lock_flocks() held. |
2307 | */ | 2307 | */ |
2308 | static | 2308 | static |
2309 | void nfsd_release_deleg_cb(struct file_lock *fl) | 2309 | void nfsd_release_deleg_cb(struct file_lock *fl) |
@@ -2318,7 +2318,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl) | |||
2318 | } | 2318 | } |
2319 | 2319 | ||
2320 | /* | 2320 | /* |
2321 | * Called from setlease() with lock_kernel() held | 2321 | * Called from setlease() with lock_flocks() held |
2322 | */ | 2322 | */ |
2323 | static | 2323 | static |
2324 | int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) | 2324 | int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index f02c0ef31578..cfeab7ce3697 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/mount.h> | 41 | #include <linux/mount.h> |
42 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
43 | #include <linux/quotaops.h> | 43 | #include <linux/quotaops.h> |
44 | #include <linux/smp_lock.h> | ||
45 | 44 | ||
46 | #define MLOG_MASK_PREFIX ML_SUPER | 45 | #define MLOG_MASK_PREFIX ML_SUPER |
47 | #include <cluster/masklog.h> | 46 | #include <cluster/masklog.h> |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 9c2b5f484879..3ddb6068177c 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/limits.h> | 16 | #include <linux/limits.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/sysctl.h> | 19 | #include <linux/sysctl.h> |
21 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
22 | 21 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index 431a0ed610c8..5d431bacbea9 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/fcntl.h> | 9 | #include <linux/fcntl.h> |
10 | #include <linux/file.h> | 10 | #include <linux/file.h> |
11 | #include <linux/uio.h> | 11 | #include <linux/uio.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/fsnotify.h> | 12 | #include <linux/fsnotify.h> |
14 | #include <linux/security.h> | 13 | #include <linux/security.h> |
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 41656d40dc5c..0bae036831e2 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/reiserfs_acl.h> | 8 | #include <linux/reiserfs_acl.h> |
9 | #include <linux/reiserfs_xattr.h> | 9 | #include <linux/reiserfs_xattr.h> |
10 | #include <linux/exportfs.h> | 10 | #include <linux/exportfs.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/pagemap.h> | 11 | #include <linux/pagemap.h> |
13 | #include <linux/highmem.h> | 12 | #include <linux/highmem.h> |
14 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index adf22b485cea..bd9763e76bae 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/time.h> | 9 | #include <linux/time.h> |
10 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
11 | #include <linux/pagemap.h> | 11 | #include <linux/pagemap.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/compat.h> | 12 | #include <linux/compat.h> |
14 | 13 | ||
15 | /* | 14 | /* |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 076c8b194682..d31bce1a9f90 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/fcntl.h> | 43 | #include <linux/fcntl.h> |
44 | #include <linux/stat.h> | 44 | #include <linux/stat.h> |
45 | #include <linux/string.h> | 45 | #include <linux/string.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/buffer_head.h> | 46 | #include <linux/buffer_head.h> |
48 | #include <linux/workqueue.h> | 47 | #include <linux/workqueue.h> |
49 | #include <linux/writeback.h> | 48 | #include <linux/writeback.h> |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 3bf7a6457f4d..b243117b8752 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
29 | #include <linux/namei.h> | 29 | #include <linux/namei.h> |
30 | #include <linux/crc32.h> | 30 | #include <linux/crc32.h> |
31 | #include <linux/smp_lock.h> | ||
32 | 31 | ||
33 | struct file_system_type reiserfs_fs_type; | 32 | struct file_system_type reiserfs_fs_type; |
34 | 33 | ||