diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsfs.c | 100 | ||||
-rw-r--r-- | fs/cifs/file.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/fscache/page.c | 14 | ||||
-rw-r--r-- | fs/libfs.c | 2 | ||||
-rw-r--r-- | fs/namei.c | 7 |
6 files changed, 42 insertions, 85 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3e2989976297..bc4b12ca537b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <linux/namei.h> | ||
38 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
39 | #include "cifsfs.h" | 40 | #include "cifsfs.h" |
40 | #include "cifspdu.h" | 41 | #include "cifspdu.h" |
@@ -542,14 +543,12 @@ static const struct super_operations cifs_super_ops = { | |||
542 | static struct dentry * | 543 | static struct dentry * |
543 | cifs_get_root(struct smb_vol *vol, struct super_block *sb) | 544 | cifs_get_root(struct smb_vol *vol, struct super_block *sb) |
544 | { | 545 | { |
545 | int xid, rc; | 546 | struct dentry *dentry; |
546 | struct inode *inode; | ||
547 | struct qstr name; | ||
548 | struct dentry *dparent = NULL, *dchild = NULL, *alias; | ||
549 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 547 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
550 | unsigned int i, full_len, len; | 548 | char *full_path = NULL; |
551 | char *full_path = NULL, *pstart; | 549 | char *s, *p; |
552 | char sep; | 550 | char sep; |
551 | int xid; | ||
553 | 552 | ||
554 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 553 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
555 | cifs_sb_master_tcon(cifs_sb)); | 554 | cifs_sb_master_tcon(cifs_sb)); |
@@ -560,73 +559,32 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
560 | 559 | ||
561 | xid = GetXid(); | 560 | xid = GetXid(); |
562 | sep = CIFS_DIR_SEP(cifs_sb); | 561 | sep = CIFS_DIR_SEP(cifs_sb); |
563 | dparent = dget(sb->s_root); | 562 | dentry = dget(sb->s_root); |
564 | full_len = strlen(full_path); | 563 | p = s = full_path; |
565 | full_path[full_len] = sep; | 564 | |
566 | pstart = full_path + 1; | 565 | do { |
567 | 566 | struct inode *dir = dentry->d_inode; | |
568 | for (i = 1, len = 0; i <= full_len; i++) { | 567 | struct dentry *child; |
569 | if (full_path[i] != sep || !len) { | 568 | |
570 | len++; | 569 | /* skip separators */ |
571 | continue; | 570 | while (*s == sep) |
572 | } | 571 | s++; |
573 | 572 | if (!*s) | |
574 | full_path[i] = 0; | 573 | break; |
575 | cFYI(1, "get dentry for %s", pstart); | 574 | p = s++; |
576 | 575 | /* next separator */ | |
577 | name.name = pstart; | 576 | while (*s && *s != sep) |
578 | name.len = len; | 577 | s++; |
579 | name.hash = full_name_hash(pstart, len); | 578 | |
580 | dchild = d_lookup(dparent, &name); | 579 | mutex_lock(&dir->i_mutex); |
581 | if (dchild == NULL) { | 580 | child = lookup_one_len(p, dentry, s - p); |
582 | cFYI(1, "not exists"); | 581 | mutex_unlock(&dir->i_mutex); |
583 | dchild = d_alloc(dparent, &name); | 582 | dput(dentry); |
584 | if (dchild == NULL) { | 583 | dentry = child; |
585 | dput(dparent); | 584 | } while (!IS_ERR(dentry)); |
586 | dparent = ERR_PTR(-ENOMEM); | ||
587 | goto out; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | cFYI(1, "get inode"); | ||
592 | if (dchild->d_inode == NULL) { | ||
593 | cFYI(1, "not exists"); | ||
594 | inode = NULL; | ||
595 | if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) | ||
596 | rc = cifs_get_inode_info_unix(&inode, full_path, | ||
597 | sb, xid); | ||
598 | else | ||
599 | rc = cifs_get_inode_info(&inode, full_path, | ||
600 | NULL, sb, xid, NULL); | ||
601 | if (rc) { | ||
602 | dput(dchild); | ||
603 | dput(dparent); | ||
604 | dparent = ERR_PTR(rc); | ||
605 | goto out; | ||
606 | } | ||
607 | alias = d_materialise_unique(dchild, inode); | ||
608 | if (alias != NULL) { | ||
609 | dput(dchild); | ||
610 | if (IS_ERR(alias)) { | ||
611 | dput(dparent); | ||
612 | dparent = ERR_PTR(-EINVAL); /* XXX */ | ||
613 | goto out; | ||
614 | } | ||
615 | dchild = alias; | ||
616 | } | ||
617 | } | ||
618 | cFYI(1, "parent %p, child %p", dparent, dchild); | ||
619 | |||
620 | dput(dparent); | ||
621 | dparent = dchild; | ||
622 | len = 0; | ||
623 | pstart = full_path + i + 1; | ||
624 | full_path[i] = sep; | ||
625 | } | ||
626 | out: | ||
627 | _FreeXid(xid); | 585 | _FreeXid(xid); |
628 | kfree(full_path); | 586 | kfree(full_path); |
629 | return dparent; | 587 | return dentry; |
630 | } | 588 | } |
631 | 589 | ||
632 | static int cifs_set_super(struct super_block *sb, void *data) | 590 | static int cifs_set_super(struct super_block *sb, void *data) |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index bb71471a4d9d..a9b4a24f2a16 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1737,7 +1737,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, | |||
1737 | io_parms.pid = pid; | 1737 | io_parms.pid = pid; |
1738 | io_parms.tcon = pTcon; | 1738 | io_parms.tcon = pTcon; |
1739 | io_parms.offset = *poffset; | 1739 | io_parms.offset = *poffset; |
1740 | io_parms.length = len; | 1740 | io_parms.length = cur_len; |
1741 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, | 1741 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, |
1742 | &read_data, &buf_type); | 1742 | &read_data, &buf_type); |
1743 | pSMBr = (struct smb_com_read_rsp *)read_data; | 1743 | pSMBr = (struct smb_com_read_rsp *)read_data; |
diff --git a/fs/dcache.c b/fs/dcache.c index 6e4ea6d87774..fbdcbca40725 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1813,8 +1813,6 @@ seqretry: | |||
1813 | tname = dentry->d_name.name; | 1813 | tname = dentry->d_name.name; |
1814 | i = dentry->d_inode; | 1814 | i = dentry->d_inode; |
1815 | prefetch(tname); | 1815 | prefetch(tname); |
1816 | if (i) | ||
1817 | prefetch(i); | ||
1818 | /* | 1816 | /* |
1819 | * This seqcount check is required to ensure name and | 1817 | * This seqcount check is required to ensure name and |
1820 | * len are loaded atomically, so as not to walk off the | 1818 | * len are loaded atomically, so as not to walk off the |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 2f343b4d7a7d..3f7a59bfa7ad 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -976,16 +976,12 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | |||
976 | 976 | ||
977 | pagevec_init(&pvec, 0); | 977 | pagevec_init(&pvec, 0); |
978 | next = 0; | 978 | next = 0; |
979 | while (next <= (loff_t)-1 && | 979 | do { |
980 | pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE) | 980 | if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) |
981 | ) { | 981 | break; |
982 | for (i = 0; i < pagevec_count(&pvec); i++) { | 982 | for (i = 0; i < pagevec_count(&pvec); i++) { |
983 | struct page *page = pvec.pages[i]; | 983 | struct page *page = pvec.pages[i]; |
984 | pgoff_t page_index = page->index; | 984 | next = page->index; |
985 | |||
986 | ASSERTCMP(page_index, >=, next); | ||
987 | next = page_index + 1; | ||
988 | |||
989 | if (PageFsCache(page)) { | 985 | if (PageFsCache(page)) { |
990 | __fscache_wait_on_page_write(cookie, page); | 986 | __fscache_wait_on_page_write(cookie, page); |
991 | __fscache_uncache_page(cookie, page); | 987 | __fscache_uncache_page(cookie, page); |
@@ -993,7 +989,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | |||
993 | } | 989 | } |
994 | pagevec_release(&pvec); | 990 | pagevec_release(&pvec); |
995 | cond_resched(); | 991 | cond_resched(); |
996 | } | 992 | } while (++next); |
997 | 993 | ||
998 | _leave(""); | 994 | _leave(""); |
999 | } | 995 | } |
diff --git a/fs/libfs.c b/fs/libfs.c index c88eab55aec9..275ca4749a2e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -822,7 +822,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, | |||
822 | goto out; | 822 | goto out; |
823 | 823 | ||
824 | attr->set_buf[size] = '\0'; | 824 | attr->set_buf[size] = '\0'; |
825 | val = simple_strtol(attr->set_buf, NULL, 0); | 825 | val = simple_strtoll(attr->set_buf, NULL, 0); |
826 | ret = attr->set(attr->data, val); | 826 | ret = attr->set(attr->data, val); |
827 | if (ret == 0) | 827 | if (ret == 0) |
828 | ret = len; /* on success, claim we got the whole input */ | 828 | ret = len; /* on success, claim we got the whole input */ |
diff --git a/fs/namei.c b/fs/namei.c index 5c867dd1c0b3..14ab8d3f2f0c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -942,7 +942,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
942 | * Don't forget we might have a non-mountpoint managed dentry | 942 | * Don't forget we might have a non-mountpoint managed dentry |
943 | * that wants to block transit. | 943 | * that wants to block transit. |
944 | */ | 944 | */ |
945 | *inode = path->dentry->d_inode; | ||
946 | if (unlikely(managed_dentry_might_block(path->dentry))) | 945 | if (unlikely(managed_dentry_might_block(path->dentry))) |
947 | return false; | 946 | return false; |
948 | 947 | ||
@@ -955,6 +954,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
955 | path->mnt = mounted; | 954 | path->mnt = mounted; |
956 | path->dentry = mounted->mnt_root; | 955 | path->dentry = mounted->mnt_root; |
957 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); | 956 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); |
957 | /* | ||
958 | * Update the inode too. We don't need to re-check the | ||
959 | * dentry sequence number here after this d_inode read, | ||
960 | * because a mount-point is always pinned. | ||
961 | */ | ||
962 | *inode = path->dentry->d_inode; | ||
958 | } | 963 | } |
959 | return true; | 964 | return true; |
960 | } | 965 | } |