[CIFS] POSIX extensions, SetFSInfo added
authorJeremy Allison <jra@samba.org>
Thu, 23 Jun 2005 00:26:35 +0000 (17:26 -0700)
committerSteve French <sfrench@hera.kernel.org>
Thu, 23 Jun 2005 00:26:35 +0000 (17:26 -0700)
Signed-off-by: Steve French@sfrench@us.ibm.com
Signed-off-by: Jeremy Allison (jra@samba.org)
13 files changed:
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/fcntl.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/readdir.c
fs/cifs/xattr.c

index ec00d61d53080b1b5e771ba3b0d0d2a83ce6e30a..5dc5fe6b486d30108481190f8c8aac58c790144b 100644 (file)
@@ -24,6 +24,7 @@
 #define CIFS_MOUNT_DIRECT_IO    8 /* do not write nor read through page cache */
 #define CIFS_MOUNT_NO_XATTR  0x10 /* if set - disable xattr support */
 #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
+#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
 
 struct cifs_sb_info {
        struct cifsTconInfo *tcon;      /* primary mount */
index 4ed9c13fff550447fe56d2db1ffd839626fb241c..d3773e57acf99e75aa490f59d89bc18c9a133458 100644 (file)
@@ -309,6 +309,13 @@ CIFS_SB(struct super_block *sb)
        return sb->s_fs_info;
 }
 
+static inline const char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
+{
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
+               return '/';
+       else
+               return '\\';
+}
 
 /* one of these for every pending CIFS request to the server */
 struct mid_q_entry {
index aede6a81316794a1a20de497c9684f96e20f6f0c..84d37f8e986e470ab1534a2639277dedc85242f6 100644 (file)
@@ -59,6 +59,7 @@
 #define TRANS2_FIND_FIRST             0x01
 #define TRANS2_FIND_NEXT              0x02
 #define TRANS2_QUERY_FS_INFORMATION   0x03
+#define TRANS2_SET_FS_INFORMATION     0x04
 #define TRANS2_QUERY_PATH_INFORMATION 0x05
 #define TRANS2_SET_PATH_INFORMATION   0x06
 #define TRANS2_QUERY_FILE_INFORMATION 0x07
@@ -1411,6 +1412,43 @@ typedef struct smb_com_transaction_qfsi_rsp {
        __u8 Pad;               /* may be three bytes *//* followed by data area */
 } TRANSACTION2_QFSI_RSP;
 
+
+/* SETFSInfo Levels */
+#define SMB_SET_CIFS_UNIX_INFO    0x200
+typedef struct smb_com_transaction2_setfsi_req {
+       struct smb_hdr hdr;     /* wct = 15 */
+       __le16 TotalParameterCount;
+       __le16 TotalDataCount;
+       __le16 MaxParameterCount;
+       __le16 MaxDataCount;
+       __u8 MaxSetupCount;
+       __u8 Reserved;
+       __le16 Flags;
+       __le32 Timeout;
+       __u16 Reserved2;
+       __le16 ParameterCount;  /* 4 */
+       __le16 ParameterOffset;
+       __le16 DataCount;       /* 12 */
+       __le16 DataOffset;
+       __u8 SetupCount;        /* one */
+       __u8 Reserved3;
+       __le16 SubCommand;      /* TRANS2_SET_FS_INFORMATION */
+       __le16 ByteCount;
+       __u8 Pad;
+       __u16 FileNum;          /* Parameters start. */
+       __le16 InformationLevel;/* Parameters end. */
+       __le16 ClientUnixMajor; /* Data start. */
+       __le16 ClientUnixMinor;
+       __le64 ClientUnixCap;   /* Data end */
+} TRANSACTION2_SETFSI_REQ;
+
+typedef struct smb_com_transaction2_setfsi_rsp {
+       struct smb_hdr hdr;     /* wct = 10 */
+       struct trans2_resp t2;
+       __u16 ByteCount;
+} TRANSACTION2_SETFSI_RSP;
+
+
 typedef struct smb_com_transaction2_get_dfs_refer_req {
        struct smb_hdr hdr;     /* wct = 15 */
        __le16 TotalParameterCount;
@@ -1551,12 +1589,20 @@ typedef struct {
        __le16 MinorVersionNumber;
        __le64 Capability;
 } FILE_SYSTEM_UNIX_INFO;       /* Unix extensions info, level 0x200 */
+
+/* Version numbers for CIFS UNIX major and minor. */
+#define CIFS_UNIX_MAJOR_VERSION 1
+#define CIFS_UNIX_MINOR_VERSION 0
+
 /* Linux/Unix extensions capability flags */
 #define CIFS_UNIX_FCNTL_CAP             0x00000001 /* support for fcntl locks */
 #define CIFS_UNIX_POSIX_ACL_CAP         0x00000002 /* support getfacl/setfacl */
 #define CIFS_UNIX_XATTR_CAP             0x00000004 /* support new namespace   */
 #define CIFS_UNIX_EXTATTR_CAP           0x00000008 /* support chattr/chflag   */
+#define CIFS_UNIX_POSIX_PATHNAMES_CAP   0x00000010 /* Use POSIX pathnames on the wire. */
+
 #define CIFS_POSIX_EXTENSIONS           0x00000010 /* support for new QFSInfo */
+
 typedef struct {
        /* For undefined recommended transfer size return -1 in that field */
        __le32 OptimalTransferSize;  /* bsize on some os, iosize on other os */
index ea239dea571e1f0a02374079ca0e918bf072cb01..db2adf0b206c2922aba0da50a3857d338b7de1dc 100644 (file)
@@ -40,7 +40,7 @@ extern unsigned int _GetXid(void);
 extern void _FreeXid(unsigned int);
 #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
 #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));}
-extern char *build_path_from_dentry(struct dentry *);
+extern char *build_path_from_dentry(struct dentry *, const struct cifs_sb_info *cifs_sb);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern void renew_parental_timestamps(struct dentry *direntry);
 extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
@@ -89,7 +89,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 
 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
             const char *searchName, const struct nls_table *nls_codepage,
-            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map);
+            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
 
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
             __u16 searchHandle, struct cifs_search_info * psrch_inf);
@@ -125,6 +125,9 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
                        int remap);
 extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
                        struct kstatfs *FSData);
+extern int CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
+                       __u64 cap);
+
 extern int CIFSSMBQFSAttributeInfo(const int xid,
                        struct cifsTconInfo *tcon);
 extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
index b31158a2643dad476fef09a9a5e4d94a693487d2..81c9d3f393f562f46d42ddd54f85876d24d23d0e 100644 (file)
@@ -2416,7 +2416,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
              const char *searchName, 
              const struct nls_table *nls_codepage,
              __u16 *   pnetfid,
-             struct cifs_search_info * psrch_inf, int remap)
+             struct cifs_search_info * psrch_inf, int remap, const char dirsep)
 {
 /* level 257 SMB_ */
        TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2443,7 +2443,7 @@ findFirstRetry:
                it got remapped to 0xF03A as if it were part of the
                directory name instead of a wildcard */
                name_len *= 2;
-               pSMB->FileName[name_len] = '\\';
+               pSMB->FileName[name_len] = dirsep;
                pSMB->FileName[name_len+1] = 0;
                pSMB->FileName[name_len+2] = '*';
                pSMB->FileName[name_len+3] = 0;
@@ -2457,7 +2457,7 @@ findFirstRetry:
                if(name_len > buffersize-header)
                        free buffer exit; BB */
                strncpy(pSMB->FileName, searchName, name_len);
-               pSMB->FileName[name_len] = '\\';
+               pSMB->FileName[name_len] = dirsep;
                pSMB->FileName[name_len+1] = '*';
                pSMB->FileName[name_len+2] = 0;
                name_len += 3;
@@ -3265,6 +3265,77 @@ QFSUnixRetry:
        return rc;
 }
 
+int
+CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
+{
+/* level 0x200  SMB_SET_CIFS_UNIX_INFO */
+       TRANSACTION2_SETFSI_REQ *pSMB = NULL;
+       TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
+       int rc = 0;
+       int bytes_returned = 0;
+       __u16 params, param_offset, offset, byte_count;
+
+       cFYI(1, ("In SETFSUnixInfo"));
+SETFSUnixRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       params = 4;     /* 2 bytes zero followed by info level. */
+       pSMB->MaxSetupCount = 0;
+       pSMB->Reserved = 0;
+       pSMB->Flags = 0;
+       pSMB->Timeout = 0;
+       pSMB->Reserved2 = 0;
+       param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
+       offset = param_offset + params;
+
+       pSMB->MaxParameterCount = cpu_to_le16(4);
+       pSMB->MaxDataCount = cpu_to_le16(100);  /* BB find exact max SMB PDU from sess structure BB */
+       pSMB->SetupCount = 1;
+       pSMB->Reserved3 = 0;
+       pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
+       byte_count = 1 /* pad */ + params + 12;
+
+       pSMB->DataCount = cpu_to_le16(12);
+       pSMB->ParameterCount = cpu_to_le16(params);
+       pSMB->TotalDataCount = pSMB->DataCount;
+       pSMB->TotalParameterCount = pSMB->ParameterCount;
+       pSMB->ParameterOffset = cpu_to_le16(param_offset);
+       pSMB->DataOffset = cpu_to_le16(offset);
+
+       /* Params. */
+       pSMB->FileNum = 0;
+       pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
+
+       /* Data. */
+       pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
+       pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
+       pSMB->ClientUnixCap = cpu_to_le64(cap);
+
+       pSMB->hdr.smb_buf_length += byte_count;
+       pSMB->ByteCount = cpu_to_le16(byte_count);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
+       } else {                /* decode response */
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+               if (rc) {
+                       rc = -EIO;      /* bad smb */
+               }
+       }
+       cifs_buf_release(pSMB);
+
+       if (rc == -EAGAIN)
+               goto SETFSUnixRetry;
+
+       return rc;
+}
+
+
 
 int
 CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
index e568cc47a7f93005518d1470696f89ee1444a1ae..bef5d6f30975aaee0541e360181d34138a146358 100644 (file)
@@ -74,6 +74,7 @@ struct smb_vol {
        unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
        unsigned direct_io:1;
        unsigned remap:1;   /* set to remap seven reserved chars in filenames */
+       unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
        unsigned int rsize;
        unsigned int wsize;
        unsigned int sockopt;
@@ -745,6 +746,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
        /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
        vol->rw = TRUE;
 
+       /* default is always to request posix paths. */
+       vol->posix_paths = 1;
+
        if (!options)
                return 1;
 
@@ -1023,6 +1027,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                        vol->remap = 1;
                } else if (strnicmp(data, "nomapchars", 10) == 0) {
                        vol->remap = 0;
+               } else if (strnicmp(data, "posixpaths", 10) == 0) {
+                       vol->posix_paths = 1;
+               } else if (strnicmp(data, "noposixpaths", 12) == 0) {
+                       vol->posix_paths = 0;
                } else if (strnicmp(data, "setuids", 7) == 0) {
                        vol->setuids = 1;
                } else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1679,6 +1687,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
                if(volume_info.no_xattr)
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
+
                if(volume_info.direct_io) {
                        cERROR(1,("mounting share using direct i/o"));
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
@@ -1781,6 +1790,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                                cFYI(1,("server negotiated posix acl support"));
                                                sb->s_flags |= MS_POSIXACL;
                                }
+
+                               /* Try and negotiate POSIX pathnames if we can. */
+                               if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
+                                   le64_to_cpu(tcon->fsUnixInfo.Capability))) {
+                                       if (!CIFSSMBSETFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP, 0))  {
+                                               cFYI(1,("negotiated posix pathnames support"));
+                                               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
+                                       } else {
+                                               cFYI(1,("posix pathnames support requested but not supported"));
+                                       }
+                               }
                        }
                }
        }
index 3f3538d4a1fad105c0a776ef5f6d6e18fef0ff6c..9360d8fb9ef78fb5b8aa99c3306066a6f415d33a 100644 (file)
@@ -43,7 +43,7 @@ renew_parental_timestamps(struct dentry *direntry)
 
 /* Note: caller must free return buffer */
 char *
-build_path_from_dentry(struct dentry *direntry)
+build_path_from_dentry(struct dentry *direntry, const struct cifs_sb_info *cifs_sb)
 {
        struct dentry *temp;
        int namelen = 0;
@@ -74,7 +74,7 @@ cifs_bp_rename_retry:
                if (namelen < 0) {
                        break;
                } else {
-                       full_path[namelen] = '\\';
+                       full_path[namelen] = CIFS_DIR_SEP(cifs_sb);
                        strncpy(full_path + namelen + 1, temp->d_name.name,
                                temp->d_name.len);
                        cFYI(0, (" name: %s ", full_path + namelen));
@@ -138,7 +138,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        pTcon = cifs_sb->tcon;
 
        down(&direntry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&direntry->d_sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);
@@ -299,7 +299,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
        pTcon = cifs_sb->tcon;
 
        down(&direntry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&direntry->d_sb->s_vfs_rename_sem);
        if(full_path == NULL)
                rc = -ENOMEM;
@@ -360,7 +360,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
        /* can not grab the rename sem here since it would
        deadlock in the cases (beginning of sys_rename itself)
        in which we already have the sb rename sem */
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        if(full_path == NULL) {
                FreeXid(xid);
                return ERR_PTR(-ENOMEM);
index 7d2a9202c39a3291969307c1c57bdc18237fca57..d47ce7f49dc313a60102fc19d7e02f36adbec247 100644 (file)
@@ -83,7 +83,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
        pTcon = cifs_sb->tcon;
 
        down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_dentry, cifs_sb);
        up(&file->f_dentry->d_sb->s_vfs_rename_sem);
 
        if(full_path == NULL) {
index 30ab70ce554716df92739f0b1643ce79053497e7..8dd11fecaaca347c2d39a7ec40b92fbdcf76d64b 100644 (file)
@@ -196,7 +196,7 @@ int cifs_open(struct inode *inode, struct file *file)
        }
 
        down(&inode->i_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_dentry, cifs_sb);
        up(&inode->i_sb->s_vfs_rename_sem);
        if (full_path == NULL) {
                FreeXid(xid);
@@ -359,7 +359,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
    those that already have the rename sem can end up causing writepage
    to get called and if the server was down that means we end up here,
    and we can never tell if the caller already has the rename_sem */
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_dentry, cifs_sb);
        if (full_path == NULL) {
                up(&pCifsFile->fh_sem);
                FreeXid(xid);
index 8d336a90025584a6fb524001ef71c123b6d881ec..95354da606d65a80df04e3a4fb22602244b55f7e 100644 (file)
@@ -412,7 +412,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
        /* Unlink can be called from rename so we can not grab the sem here
           since we deadlock otherwise */
 /*     down(&direntry->d_sb->s_vfs_rename_sem);*/
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
 /*     up(&direntry->d_sb->s_vfs_rename_sem);*/
        if (full_path == NULL) {
                FreeXid(xid);
@@ -556,7 +556,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        pTcon = cifs_sb->tcon;
 
        down(&inode->i_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&inode->i_sb->s_vfs_rename_sem);
        if (full_path == NULL) {
                FreeXid(xid);
@@ -627,7 +627,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        pTcon = cifs_sb->tcon;
 
        down(&inode->i_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&inode->i_sb->s_vfs_rename_sem);
        if (full_path == NULL) {
                FreeXid(xid);
@@ -680,8 +680,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
 
        /* we already  have the rename sem so we do not need to grab it again
           here to protect the path integrity */
-       fromName = build_path_from_dentry(source_direntry);
-       toName = build_path_from_dentry(target_direntry);
+       fromName = build_path_from_dentry(source_direntry, cifs_sb_source);
+       toName = build_path_from_dentry(target_direntry, cifs_sb_target);
        if ((fromName == NULL) || (toName == NULL)) {
                rc = -ENOMEM;
                goto cifs_rename_exit;
@@ -797,7 +797,7 @@ int cifs_revalidate(struct dentry *direntry)
 
        /* can not safely grab the rename sem here if rename calls revalidate
           since that would deadlock */
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -946,7 +946,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        pTcon = cifs_sb->tcon;
 
        down(&direntry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&direntry->d_sb->s_vfs_rename_sem);
        if (full_path == NULL) {
                FreeXid(xid);
index bde0fabfece0aeeaecd9ab4b1c2cf733009975b1..214aa816f66919aa5f37bfeedf506db0b4733769 100644 (file)
@@ -49,8 +49,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
    BB note DFS case in future though (when we may have to check) */
 
        down(&inode->i_sb->s_vfs_rename_sem);
-       fromName = build_path_from_dentry(old_file);
-       toName = build_path_from_dentry(direntry);
+       fromName = build_path_from_dentry(old_file, cifs_sb_target);
+       toName = build_path_from_dentry(direntry, cifs_sb_target);
        up(&inode->i_sb->s_vfs_rename_sem);
        if((fromName == NULL) || (toName == NULL)) {
                rc = -ENOMEM;
@@ -105,16 +105,17 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 
        xid = GetXid();
 
+       cifs_sb = CIFS_SB(inode->i_sb);
+       pTcon = cifs_sb->tcon;
+
        down(&direntry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&direntry->d_sb->s_vfs_rename_sem);
 
        if (!full_path)
                goto out_no_free;
 
        cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
-       cifs_sb = CIFS_SB(inode->i_sb);
-       pTcon = cifs_sb->tcon;
        target_path = kmalloc(PATH_MAX, GFP_KERNEL);
        if (!target_path) {
                target_path = ERR_PTR(-ENOMEM);
@@ -167,7 +168,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
        pTcon = cifs_sb->tcon;
 
        down(&inode->i_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&inode->i_sb->s_vfs_rename_sem);
 
        if(full_path == NULL) {
@@ -233,7 +234,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
 /* BB would it be safe against deadlock to grab this sem 
       even though rename itself grabs the sem and calls lookup? */
 /*       down(&inode->i_sb->s_vfs_rename_sem);*/
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
 /*       up(&inode->i_sb->s_vfs_rename_sem);*/
 
        if(full_path == NULL) {
index 487221eeddb7c1daf34919ee7a3d966348bfdf9c..42310281871c2be2237eb5906aa1ad4f874ff13f 100644 (file)
@@ -354,7 +354,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
                return -EINVAL;
 
        down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_dentry, cifs_sb);
        up(&file->f_dentry->d_sb->s_vfs_rename_sem);
 
        if(full_path == NULL) {
@@ -375,7 +375,7 @@ ffirst_retry:
 
        rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls,
                &cifsFile->netfid, &cifsFile->srch_inf,
-               cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+               cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
        if(rc == 0)
                cifsFile->invalidHandle = FALSE;
        if((rc == -EOPNOTSUPP) && 
index c1e02eff1d25a222613f48b5312cb055776abc00..f4fc8ddebba75d7de8bae505195d48261e4258f1 100644 (file)
@@ -63,7 +63,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
        pTcon = cifs_sb->tcon;
                                                                                      
        down(&sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);
@@ -118,7 +118,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
        pTcon = cifs_sb->tcon;
 
        down(&sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);
@@ -227,7 +227,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
        pTcon = cifs_sb->tcon;
 
        down(&sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);
@@ -328,7 +328,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
        pTcon = cifs_sb->tcon;
 
        down(&sb->s_vfs_rename_sem);
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(direntry, cifs_sb);
        up(&sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);