aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsfs.c100
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/fscache/page.c14
-rw-r--r--fs/libfs.c2
-rw-r--r--fs/namei.c7
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 = {
542static struct dentry * 543static struct dentry *
543cifs_get_root(struct smb_vol *vol, struct super_block *sb) 544cifs_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 }
626out:
627 _FreeXid(xid); 585 _FreeXid(xid);
628 kfree(full_path); 586 kfree(full_path);
629 return dparent; 587 return dentry;
630} 588}
631 589
632static int cifs_set_super(struct super_block *sb, void *data) 590static 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}