diff options
author | Steve French <sfrench@us.ibm.com> | 2010-05-13 18:19:32 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-05-13 18:19:32 -0400 |
commit | baa456331738b4e76a92318b62b354377a30ad80 (patch) | |
tree | 75c828a7c8a9f1b5f7f41b2e53271eafb7e561ef /fs/cifs | |
parent | aa3e5572c538d753dce11bf93532a75f95d22b40 (diff) | |
parent | 4462dc02842698f173f518c1f5ce79c0fb89395a (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.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 10 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
-rw-r--r-- | fs/cifs/inode.c | 21 |
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 | ||
511 | struct cifs_fattr { | 512 | struct 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 | ||
747 | retry_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; |