aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2011-01-09 18:18:16 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-09 18:18:16 -0500
commitacc6f11272ce4f77c40b1a6292eb198fd6aaf8c3 (patch)
tree2da3a61b6726707a89f1cf93446aabd2fb00e1f0 /fs/cifs
parent7e12eddb73d4f288b0339ee13832a34d6bc4fd90 (diff)
parent0c21e3aaf6ae85bee804a325aa29c325209180fd (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: fs/cifs/dir.c
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c16
-rw-r--r--fs/cifs/dir.c37
-rw-r--r--fs/cifs/inode.c14
-rw-r--r--fs/cifs/link.c4
-rw-r--r--fs/cifs/readdir.c6
5 files changed, 50 insertions, 27 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9df5c0b94d0f..5abfedaa5e78 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -283,10 +283,13 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
283 return 0; 283 return 0;
284} 284}
285 285
286static int cifs_permission(struct inode *inode, int mask) 286static int cifs_permission(struct inode *inode, int mask, unsigned int flags)
287{ 287{
288 struct cifs_sb_info *cifs_sb; 288 struct cifs_sb_info *cifs_sb;
289 289
290 if (flags & IPERM_FLAG_RCU)
291 return -ECHILD;
292
290 cifs_sb = CIFS_SB(inode->i_sb); 293 cifs_sb = CIFS_SB(inode->i_sb);
291 294
292 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { 295 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
@@ -298,7 +301,7 @@ static int cifs_permission(struct inode *inode, int mask)
298 on the client (above and beyond ACL on servers) for 301 on the client (above and beyond ACL on servers) for
299 servers which do not support setting and viewing mode bits, 302 servers which do not support setting and viewing mode bits,
300 so allowing client to check permissions is useful */ 303 so allowing client to check permissions is useful */
301 return generic_permission(inode, mask, NULL); 304 return generic_permission(inode, mask, flags, NULL);
302} 305}
303 306
304static struct kmem_cache *cifs_inode_cachep; 307static struct kmem_cache *cifs_inode_cachep;
@@ -334,10 +337,17 @@ cifs_alloc_inode(struct super_block *sb)
334 return &cifs_inode->vfs_inode; 337 return &cifs_inode->vfs_inode;
335} 338}
336 339
340static void cifs_i_callback(struct rcu_head *head)
341{
342 struct inode *inode = container_of(head, struct inode, i_rcu);
343 INIT_LIST_HEAD(&inode->i_dentry);
344 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
345}
346
337static void 347static void
338cifs_destroy_inode(struct inode *inode) 348cifs_destroy_inode(struct inode *inode)
339{ 349{
340 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); 350 call_rcu(&inode->i_rcu, cifs_i_callback);
341} 351}
342 352
343static void 353static void
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 521d841b1fd1..ce8014345258 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -135,9 +135,9 @@ static void setup_cifs_dentry(struct cifsTconInfo *tcon,
135 struct inode *newinode) 135 struct inode *newinode)
136{ 136{
137 if (tcon->nocase) 137 if (tcon->nocase)
138 direntry->d_op = &cifs_ci_dentry_ops; 138 d_set_d_op(direntry, &cifs_ci_dentry_ops);
139 else 139 else
140 direntry->d_op = &cifs_dentry_ops; 140 d_set_d_op(direntry, &cifs_dentry_ops);
141 d_instantiate(direntry, newinode); 141 d_instantiate(direntry, newinode);
142} 142}
143 143
@@ -421,9 +421,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
421 rc = cifs_get_inode_info_unix(&newinode, full_path, 421 rc = cifs_get_inode_info_unix(&newinode, full_path,
422 inode->i_sb, xid); 422 inode->i_sb, xid);
423 if (pTcon->nocase) 423 if (pTcon->nocase)
424 direntry->d_op = &cifs_ci_dentry_ops; 424 d_set_d_op(direntry, &cifs_ci_dentry_ops);
425 else 425 else
426 direntry->d_op = &cifs_dentry_ops; 426 d_set_d_op(direntry, &cifs_dentry_ops);
427 427
428 if (rc == 0) 428 if (rc == 0)
429 d_instantiate(direntry, newinode); 429 d_instantiate(direntry, newinode);
@@ -604,9 +604,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
604 604
605 if ((rc == 0) && (newInode != NULL)) { 605 if ((rc == 0) && (newInode != NULL)) {
606 if (pTcon->nocase) 606 if (pTcon->nocase)
607 direntry->d_op = &cifs_ci_dentry_ops; 607 d_set_d_op(direntry, &cifs_ci_dentry_ops);
608 else 608 else
609 direntry->d_op = &cifs_dentry_ops; 609 d_set_d_op(direntry, &cifs_dentry_ops);
610 d_add(direntry, newInode); 610 d_add(direntry, newInode);
611 if (posix_open) { 611 if (posix_open) {
612 filp = lookup_instantiate_filp(nd, direntry, 612 filp = lookup_instantiate_filp(nd, direntry,
@@ -634,9 +634,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
634 rc = 0; 634 rc = 0;
635 direntry->d_time = jiffies; 635 direntry->d_time = jiffies;
636 if (pTcon->nocase) 636 if (pTcon->nocase)
637 direntry->d_op = &cifs_ci_dentry_ops; 637 d_set_d_op(direntry, &cifs_ci_dentry_ops);
638 else 638 else
639 direntry->d_op = &cifs_dentry_ops; 639 d_set_d_op(direntry, &cifs_dentry_ops);
640 d_add(direntry, NULL); 640 d_add(direntry, NULL);
641 /* if it was once a directory (but how can we tell?) we could do 641 /* if it was once a directory (but how can we tell?) we could do
642 shrink_dcache_parent(direntry); */ 642 shrink_dcache_parent(direntry); */
@@ -656,6 +656,9 @@ lookup_out:
656static int 656static int
657cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 657cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
658{ 658{
659 if (nd->flags & LOOKUP_RCU)
660 return -ECHILD;
661
659 if (direntry->d_inode) { 662 if (direntry->d_inode) {
660 if (cifs_revalidate_dentry(direntry)) 663 if (cifs_revalidate_dentry(direntry))
661 return 0; 664 return 0;
@@ -700,9 +703,10 @@ const struct dentry_operations cifs_dentry_ops = {
700/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ 703/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
701}; 704};
702 705
703static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) 706static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
707 struct qstr *q)
704{ 708{
705 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 709 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
706 unsigned long hash; 710 unsigned long hash;
707 int i; 711 int i;
708 712
@@ -715,13 +719,22 @@ static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
715 return 0; 719 return 0;
716} 720}
717 721
718static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, 722static int cifs_ci_compare(const struct dentry *parent,
719 struct qstr *b) 723 const struct inode *pinode,
724 const struct dentry *dentry, const struct inode *inode,
725 unsigned int len, const char *str, const struct qstr *name)
720{ 726{
727<<<<<<< HEAD
721 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 728 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
722 729
723 if ((a->len == b->len) && 730 if ((a->len == b->len) &&
724 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) 731 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0))
732=======
733 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
734
735 if ((name->len == len) &&
736 (nls_strnicmp(codepage, name->name, str, len) == 0))
737>>>>>>> 0c21e3aaf6ae85bee804a325aa29c325209180fd
725 return 0; 738 return 0;
726 return 1; 739 return 1;
727} 740}
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 589f3e3f6e00..a853a89857a5 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -809,14 +809,14 @@ inode_has_hashed_dentries(struct inode *inode)
809{ 809{
810 struct dentry *dentry; 810 struct dentry *dentry;
811 811
812 spin_lock(&dcache_lock); 812 spin_lock(&inode->i_lock);
813 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 813 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
814 if (!d_unhashed(dentry) || IS_ROOT(dentry)) { 814 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
815 spin_unlock(&dcache_lock); 815 spin_unlock(&inode->i_lock);
816 return true; 816 return true;
817 } 817 }
818 } 818 }
819 spin_unlock(&dcache_lock); 819 spin_unlock(&inode->i_lock);
820 return false; 820 return false;
821} 821}
822 822
@@ -1319,9 +1319,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1319 to set uid/gid */ 1319 to set uid/gid */
1320 inc_nlink(inode); 1320 inc_nlink(inode);
1321 if (pTcon->nocase) 1321 if (pTcon->nocase)
1322 direntry->d_op = &cifs_ci_dentry_ops; 1322 d_set_d_op(direntry, &cifs_ci_dentry_ops);
1323 else 1323 else
1324 direntry->d_op = &cifs_dentry_ops; 1324 d_set_d_op(direntry, &cifs_dentry_ops);
1325 1325
1326 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); 1326 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1327 cifs_fill_uniqueid(inode->i_sb, &fattr); 1327 cifs_fill_uniqueid(inode->i_sb, &fattr);
@@ -1363,9 +1363,9 @@ mkdir_get_info:
1363 inode->i_sb, xid, NULL); 1363 inode->i_sb, xid, NULL);
1364 1364
1365 if (pTcon->nocase) 1365 if (pTcon->nocase)
1366 direntry->d_op = &cifs_ci_dentry_ops; 1366 d_set_d_op(direntry, &cifs_ci_dentry_ops);
1367 else 1367 else
1368 direntry->d_op = &cifs_dentry_ops; 1368 d_set_d_op(direntry, &cifs_dentry_ops);
1369 d_instantiate(direntry, newinode); 1369 d_instantiate(direntry, newinode);
1370 /* setting nlink not necessary except in cases where we 1370 /* setting nlink not necessary except in cases where we
1371 * failed to get it from the server or was set bogus */ 1371 * failed to get it from the server or was set bogus */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 85cdbf831e7b..fe2f6a93c49e 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -525,9 +525,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
525 rc); 525 rc);
526 } else { 526 } else {
527 if (pTcon->nocase) 527 if (pTcon->nocase)
528 direntry->d_op = &cifs_ci_dentry_ops; 528 d_set_d_op(direntry, &cifs_ci_dentry_ops);
529 else 529 else
530 direntry->d_op = &cifs_dentry_ops; 530 d_set_d_op(direntry, &cifs_dentry_ops);
531 d_instantiate(direntry, newinode); 531 d_instantiate(direntry, newinode);
532 } 532 }
533 } 533 }
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index a73eb9f4bdaf..ec5b68e3b928 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
79 cFYI(1, "For %s", name->name); 79 cFYI(1, "For %s", name->name);
80 80
81 if (parent->d_op && parent->d_op->d_hash) 81 if (parent->d_op && parent->d_op->d_hash)
82 parent->d_op->d_hash(parent, name); 82 parent->d_op->d_hash(parent, parent->d_inode, name);
83 else 83 else
84 name->hash = full_name_hash(name->name, name->len); 84 name->hash = full_name_hash(name->name, name->len);
85 85
@@ -103,9 +103,9 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
103 } 103 }
104 104
105 if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase) 105 if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
106 dentry->d_op = &cifs_ci_dentry_ops; 106 d_set_d_op(dentry, &cifs_ci_dentry_ops);
107 else 107 else
108 dentry->d_op = &cifs_dentry_ops; 108 d_set_d_op(dentry, &cifs_dentry_ops);
109 109
110 alias = d_materialise_unique(dentry, inode); 110 alias = d_materialise_unique(dentry, inode);
111 if (alias != NULL) { 111 if (alias != NULL) {