[CIFS] POSIX extensions, SetFSInfo added
Signed-off-by: Steve French@sfrench@us.ibm.com Signed-off-by: Jeremy Allison (jra@samba.org)
This commit is contained in:
Родитель
dfb7533b5f
Коммит
ac67055ef2
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче