aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2010-05-13 18:19:32 -0400
committerSteve French <sfrench@us.ibm.com>2010-05-13 18:19:32 -0400
commitbaa456331738b4e76a92318b62b354377a30ad80 (patch)
tree75c828a7c8a9f1b5f7f41b2e53271eafb7e561ef /fs/cifs
parentaa3e5572c538d753dce11bf93532a75f95d22b40 (diff)
parent4462dc02842698f173f518c1f5ce79c0fb89395a (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: fs/cifs/inode.c
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifsfs.c10
-rw-r--r--fs/cifs/cifsglob.h1
-rw-r--r--fs/cifs/inode.c21
4 files changed, 33 insertions, 2 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 4797787c6a44..246a167cb913 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -18,6 +18,8 @@
18#ifndef _CIFS_FS_SB_H 18#ifndef _CIFS_FS_SB_H
19#define _CIFS_FS_SB_H 19#define _CIFS_FS_SB_H
20 20
21#include <linux/backing-dev.h>
22
21#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ 23#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
22#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ 24#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ 25#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
50#ifdef CONFIG_CIFS_DFS_UPCALL 52#ifdef CONFIG_CIFS_DFS_UPCALL
51 char *mountdata; /* mount options received at mount time */ 53 char *mountdata; /* mount options received at mount time */
52#endif 54#endif
55 struct backing_dev_info bdi;
53}; 56};
54#endif /* _CIFS_FS_SB_H */ 57#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 833166372a08..78c02eb4cb1f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -97,6 +97,12 @@ cifs_read_super(struct super_block *sb, void *data,
97 if (cifs_sb == NULL) 97 if (cifs_sb == NULL)
98 return -ENOMEM; 98 return -ENOMEM;
99 99
100 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
101 if (rc) {
102 kfree(cifs_sb);
103 return rc;
104 }
105
100#ifdef CONFIG_CIFS_DFS_UPCALL 106#ifdef CONFIG_CIFS_DFS_UPCALL
101 /* copy mount params to sb for use in submounts */ 107 /* copy mount params to sb for use in submounts */
102 /* BB: should we move this after the mount so we 108 /* BB: should we move this after the mount so we
@@ -109,6 +115,7 @@ cifs_read_super(struct super_block *sb, void *data,
109 int len = strlen(data); 115 int len = strlen(data);
110 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); 116 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
111 if (cifs_sb->mountdata == NULL) { 117 if (cifs_sb->mountdata == NULL) {
118 bdi_destroy(&cifs_sb->bdi);
112 kfree(sb->s_fs_info); 119 kfree(sb->s_fs_info);
113 sb->s_fs_info = NULL; 120 sb->s_fs_info = NULL;
114 return -ENOMEM; 121 return -ENOMEM;
@@ -128,6 +135,7 @@ cifs_read_super(struct super_block *sb, void *data,
128 135
129 sb->s_magic = CIFS_MAGIC_NUMBER; 136 sb->s_magic = CIFS_MAGIC_NUMBER;
130 sb->s_op = &cifs_super_ops; 137 sb->s_op = &cifs_super_ops;
138 sb->s_bdi = &cifs_sb->bdi;
131/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) 139/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
132 sb->s_blocksize = 140 sb->s_blocksize =
133 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ 141 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
@@ -173,6 +181,7 @@ out_mount_failed:
173 } 181 }
174#endif 182#endif
175 unload_nls(cifs_sb->local_nls); 183 unload_nls(cifs_sb->local_nls);
184 bdi_destroy(&cifs_sb->bdi);
176 kfree(cifs_sb); 185 kfree(cifs_sb);
177 } 186 }
178 return rc; 187 return rc;
@@ -204,6 +213,7 @@ cifs_put_super(struct super_block *sb)
204#endif 213#endif
205 214
206 unload_nls(cifs_sb->local_nls); 215 unload_nls(cifs_sb->local_nls);
216 bdi_destroy(&cifs_sb->bdi);
207 kfree(cifs_sb); 217 kfree(cifs_sb);
208 218
209 unlock_kernel(); 219 unlock_kernel();
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 4a99487400f3..a88479ceaad5 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -507,6 +507,7 @@ struct dfs_info3_param {
507#define CIFS_FATTR_DFS_REFERRAL 0x1 507#define CIFS_FATTR_DFS_REFERRAL 0x1
508#define CIFS_FATTR_DELETE_PENDING 0x2 508#define CIFS_FATTR_DELETE_PENDING 0x2
509#define CIFS_FATTR_NEED_REVAL 0x4 509#define CIFS_FATTR_NEED_REVAL 0x4
510#define CIFS_FATTR_INO_COLLISION 0x8
510 511
511struct cifs_fattr { 512struct cifs_fattr {
512 u32 cf_flags; 513 u32 cf_flags;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b35cb031c20c..5b042fc46450 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -715,6 +715,16 @@ cifs_find_inode(struct inode *inode, void *opaque)
715 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) 715 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
716 return 0; 716 return 0;
717 717
718 /*
719 * uh oh -- it's a directory. We can't use it since hardlinked dirs are
720 * verboten. Disable serverino and return it as if it were found, the
721 * caller can discard it, generate a uniqueid and retry the find
722 */
723 if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
724 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
725 cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
726 }
727
718 return 1; 728 return 1;
719} 729}
720 730
@@ -734,15 +744,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
734 unsigned long hash; 744 unsigned long hash;
735 struct inode *inode; 745 struct inode *inode;
736 746
747retry_iget5_locked:
737 cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid); 748 cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
738 749
739 /* hash down to 32-bits on 32-bit arch */ 750 /* hash down to 32-bits on 32-bit arch */
740 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); 751 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
741 752
742 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); 753 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
743
744 /* we have fattrs in hand, update the inode */
745 if (inode) { 754 if (inode) {
755 /* was there a problematic inode number collision? */
756 if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
757 iput(inode);
758 fattr->cf_uniqueid = iunique(sb, ROOT_I);
759 fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
760 goto retry_iget5_locked;
761 }
762
746 cifs_fattr_to_inode(inode, fattr); 763 cifs_fattr_to_inode(inode, fattr);
747 if (sb->s_flags & MS_NOATIME) 764 if (sb->s_flags & MS_NOATIME)
748 inode->i_flags |= S_NOATIME | S_NOCMTIME; 765 inode->i_flags |= S_NOATIME | S_NOCMTIME;