Diff
Modified: trunk/fs/cifs/cifsfs.c (9727 => 9728)
--- trunk/fs/cifs/cifsfs.c 2011-03-18 04:36:07 UTC (rev 9727)
+++ trunk/fs/cifs/cifsfs.c 2011-03-18 06:45:40 UTC (rev 9728)
@@ -177,6 +177,13 @@
rc = -ENOMEM;
goto out_no_root;
}
+
+ /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
+ if (cifs_sb_master_tcon(cifs_sb)->nocase)
+ sb->s_d_op = &cifs_ci_dentry_ops;
+ else
+ sb->s_d_op = &cifs_dentry_ops;
+
#ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cFYI(1, "export ops supported");
@@ -290,6 +297,9 @@
{
struct cifs_sb_info *cifs_sb;
+ if (flags & IPERM_FLAG_RCU)
+ return -ECHILD;
+
cifs_sb = CIFS_SB(inode->i_sb);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
@@ -301,8 +311,7 @@
on the client (above and beyond ACL on servers) for
servers which do not support setting and viewing mode bits,
so allowing client to check permissions is useful */
- /* return generic_permission(inode, mask, flags, NULL); */
- return generic_permission(inode, mask, NULL);
+ return generic_permission(inode, mask, flags, NULL);
}
static struct kmem_cache *cifs_inode_cachep;
@@ -340,14 +349,20 @@
return &cifs_inode->vfs_inode;
}
-static void
-cifs_destroy_inode(struct inode *inode)
+static void cifs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
}
static void
+cifs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, cifs_i_callback);
+}
+
+static void
cifs_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
Modified: trunk/fs/cifs/dir.c (9727 => 9728)
--- trunk/fs/cifs/dir.c 2011-03-18 04:36:07 UTC (rev 9727)
+++ trunk/fs/cifs/dir.c 2011-03-18 06:45:40 UTC (rev 9728)
@@ -631,6 +631,9 @@
static int
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
{
+ if (nd->flags & LOOKUP_RCU)
+ return -ECHILD;
+
if (direntry->d_inode) {
if (cifs_revalidate_dentry(direntry))
return 0;
@@ -672,6 +675,7 @@
const struct dentry_operations cifs_dentry_ops = {
.d_revalidate = cifs_d_revalidate,
+ .d_automount = cifs_dfs_d_automount,
/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
};
@@ -708,4 +712,5 @@
.d_revalidate = cifs_d_revalidate,
.d_hash = cifs_ci_hash,
.d_compare = cifs_ci_compare,
+ .d_automount = cifs_dfs_d_automount,
};
Modified: trunk/fs/cifs/inode.c (9727 => 9728)
--- trunk/fs/cifs/inode.c 2011-03-18 04:36:07 UTC (rev 9727)
+++ trunk/fs/cifs/inode.c 2011-03-18 06:45:40 UTC (rev 9728)
@@ -170,6 +170,9 @@
inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
}
spin_unlock(&inode->i_lock);
+
+ if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
+ inode->i_flags |= S_AUTOMOUNT;
cifs_set_ops(inode);
}
Modified: trunk/fs/cifs/readdir.c (9727 => 9728)
--- trunk/fs/cifs/readdir.c 2011-03-18 04:36:07 UTC (rev 9727)
+++ trunk/fs/cifs/readdir.c 2011-03-18 06:45:40 UTC (rev 9728)
@@ -79,7 +79,7 @@
cFYI(1, "For %s", name->name);
if (parent->d_op && parent->d_op->d_hash)
- parent->d_op->d_hash(parent, name);
+ parent->d_op->d_hash(parent, parent->d_inode, name);
else
name->hash = full_name_hash(name->name, name->len);
Modified: trunk/fs/cifs/sess.c (9727 => 9728)
--- trunk/fs/cifs/sess.c 2011-03-18 04:36:07 UTC (rev 9727)
+++ trunk/fs/cifs/sess.c 2011-03-18 06:45:40 UTC (rev 9728)
@@ -814,7 +814,7 @@
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
capabilities |= CAP_EXTENDED_SECURITY;
pSMB->req.Capabilities |= cpu_to_le32(capabilities);
- switch (phase) {
+ switch(phase) {
case NtLmNegotiate:
build_ntlmssp_negotiate_blob(
pSMB->req.SecurityBlob, ses);