[linux-cifs-client] mount of IPC$ breaks with iget patch

Steve French smfrench at gmail.com
Mon Aug 11 22:59:26 GMT 2008


In looking at network named pipe support on cifs, I noticed that the patch:

commit ce634ab28e7dbcc13ebe6e7bc5bc7de4f8def4c8
Author: David Howells <dhowells at redhat.com>
Date:   Thu Feb 7 00:15:33 2008 -0800

    iget: stop CIFS from using iget() and read_inode()

seemed to break mounts to IPC$ (the interprocess communication share).

Looks like the following (or something similar) was missing from the
original patch:

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 28a2209..b6aac5d 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -649,7 +649,7 @@ struct inode *cifs_iget(struct super_block *sb,
unsigned long ino)
                inode->i_fop = &simple_dir_operations;
                inode->i_uid = cifs_sb->mnt_uid;
                inode->i_gid = cifs_sb->mnt_gid;
-               _FreeXid(xid);
+       } else if (rc) {
                iget_failed(inode);
                return ERR_PTR(rc);
        }

Since you can not do QueryPathInfo on pipes, the IPC$ mount is special
cased.  See below for the fixed version of that function.

/* gets root inode */
struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
{
        int xid;
        struct cifs_sb_info *cifs_sb;
        struct inode *inode;
        long rc;

        inode = iget_locked(sb, ino);
        if (!inode)
                return ERR_PTR(-ENOMEM);
        if (!(inode->i_state & I_NEW))
                return inode;

        cifs_sb = CIFS_SB(inode->i_sb);
        xid = GetXid();

        if (cifs_sb->tcon->unix_ext)
                rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
        else
                rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid,
                                         NULL);
        if (rc && cifs_sb->tcon->ipc) {
                cFYI(1, ("ipc connection - fake read inode"));
                inode->i_mode |= S_IFDIR;
                inode->i_nlink = 2;
                inode->i_op = &cifs_ipc_inode_ops;
                inode->i_fop = &simple_dir_operations;
                inode->i_uid = cifs_sb->mnt_uid;
                inode->i_gid = cifs_sb->mnt_gid;
        } else if (rc) {
                iget_failed(inode);
                return ERR_PTR(rc);
        }

        unlock_new_inode(inode);

        /* can not call macro FreeXid here since in a void func
         * TODO: This is no longer true
         */
        _FreeXid(xid);
        return inode;
}



The
-- 
Thanks,

Steve


More information about the linux-cifs-client mailing list