spin_unlock(&inode->i_lock);
}
-static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon,
- const char *search_path)
+static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb,
+ const char *search_path)
{
int tree_len;
int path_len;
+ int i;
char *tmp_path;
+ struct cifsTconInfo *pTcon = cifs_sb->tcon;
if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
return search_path;
return search_path;
strncpy(tmp_path, pTcon->treeName, tree_len);
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
+ for (i = 0; i < tree_len; i++) {
+ if (tmp_path[i] == '\\')
+ tmp_path[i] = '/';
+ }
strncpy(tmp_path+tree_len, search_path, path_len);
tmp_path[tree_len+path_len] = 0;
return tmp_path;
pTcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", search_path));
- full_path = cifs_get_search_path(pTcon, search_path);
+ full_path = cifs_get_search_path(cifs_sb, search_path);
try_again_CIFSSMBUnixQPathInfo:
/* could have done a find first instead but this returns more info */
if (rc) {
if (rc == -EREMOTE && !is_dfs_referral) {
is_dfs_referral = true;
- full_path = search_path;
+ if (full_path != search_path) {
+ kfree(full_path);
+ full_path = search_path;
+ }
goto try_again_CIFSSMBUnixQPathInfo;
}
goto cgiiu_exit;
struct cifs_sb_info *cifs_sb, int xid)
{
int rc;
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
struct cifsTconInfo *pTcon = cifs_sb->tcon;
char buf[24];
int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path, FILE_ALL_INFO *pfindData,
- struct super_block *sb, int xid)
+ struct super_block *sb, int xid, const __u16 *pfid)
{
int rc = 0;
struct cifsTconInfo *pTcon;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
const unsigned char *full_path = NULL;
char *buf = NULL;
- int adjustTZ = FALSE;
+ bool adjustTZ = false;
bool is_dfs_referral = false;
pTcon = cifs_sb->tcon;
return -ENOMEM;
pfindData = (FILE_ALL_INFO *)buf;
- full_path = cifs_get_search_path(pTcon, search_path);
+ full_path = cifs_get_search_path(cifs_sb, search_path);
try_again_CIFSSMBQPathInfo:
/* could do find first instead but this returns more info */
pfindData, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- adjustTZ = TRUE;
+ adjustTZ = true;
}
}
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if (rc) {
if (rc == -EREMOTE && !is_dfs_referral) {
is_dfs_referral = true;
- full_path = search_path;
+ if (full_path != search_path) {
+ kfree(full_path);
+ full_path = search_path;
+ }
goto try_again_CIFSSMBQPathInfo;
}
goto cgii_exit;
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
cFYI(1, ("Getting mode bits from ACL"));
- acl_to_uid_mode(inode, search_path);
+ acl_to_uid_mode(inode, search_path, pfid);
}
#endif
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
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);
+ 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;
} else if (rc == -ENOENT) {
d_drop(direntry);
} else if (rc == -ETXTBSY) {
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
rc = -EOPNOTSUPP;
if (rc == -EOPNOTSUPP) {
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
/* rc = CIFSSMBSetAttrLegacy(xid, pTcon,
full_path,
if (direntry->d_inode)
drop_nlink(direntry->d_inode);
} else if (rc == -ETXTBSY) {
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, full_path,
inode->i_sb, xid);
else
rc = cifs_get_inode_info(&newinode, full_path, NULL,
- inode->i_sb, xid);
+ inode->i_sb, xid, NULL);
if (pTcon->nocase)
direntry->d_op = &cifs_ci_dentry_ops;
cFYI(1, ("rename rc %d", rc));
if ((rc == -EIO) || (rc == -EEXIST)) {
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
/* BB FIXME Is Generic Read correct for rename? */
struct cifsInodeInfo *cifsInode;
loff_t local_size;
struct timespec local_mtime;
- int invalidate_inode = FALSE;
+ bool invalidate_inode = false;
if (direntry->d_inode == NULL)
return -ENOENT;
}
} else {
rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
- direntry->d_sb, xid);
+ direntry->d_sb, xid, NULL);
if (rc) {
cFYI(1, ("error on getting revalidate info %d", rc));
/* if (rc != -ENOENT)
only ones who could have modified the file and the
server copy is staler than ours */
} else {
- invalidate_inode = TRUE;
+ invalidate_inode = true;
}
}
int rc = -EACCES;
struct cifsFileInfo *open_file = NULL;
FILE_BASIC_INFO time_buf;
- int set_time = FALSE;
- int set_dosattr = FALSE;
+ bool set_time = false;
+ bool set_dosattr = false;
__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
}
cifsInode = CIFS_I(direntry->d_inode);
- /* BB check if we need to refresh inode from server now ? BB */
-
- if (attrs->ia_valid & ATTR_SIZE) {
+ if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
/*
- Flush data before changing file size on server. If the
+ Flush data before changing file size or changing the last
+ write time of the file on the server. If the
flush returns error, store it to report later and continue.
BB: This should be smarter. Why bother flushing pages that
will be truncated anyway? Also, should we error out here if
CIFS_I(direntry->d_inode)->write_behind_rc = rc;
rc = 0;
}
+ }
+ if (attrs->ia_valid & ATTR_SIZE) {
/* To avoid spurious oplock breaks from server, in the case of
inodes that we already have open, avoid doing path based
setting of file size if we can do it by handle.
__u16 nfid = open_file->netfid;
__u32 npid = open_file->pid;
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
- nfid, npid, FALSE);
+ nfid, npid, false);
atomic_dec(&open_file->wrtPending);
cFYI(1, ("SetFSize for attrs rc = %d", rc));
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
it was found or because there was an error setting
it by handle */
rc = CIFSSMBSetEOF(xid, pTcon, full_path,
- attrs->ia_size, FALSE,
+ attrs->ia_size, false,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
__u16 netfid;
- int oplock = FALSE;
+ int oplock = 0;
rc = SMBLegacyOpen(xid, pTcon, full_path,
FILE_OPEN,
/* Server is ok setting allocation size implicitly - no need
to call:
- CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE,
+ CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true,
cifs_sb->local_nls);
*/
#endif
/* not writeable */
if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
- set_dosattr = TRUE;
+ set_dosattr = true;
time_buf.Attributes =
cpu_to_le32(cifsInode->cifsAttrs |
ATTR_READONLY);
not be able to write to it - so if any write
bit is enabled for user or group or other we
need to at least try to remove r/o dos attr */
- set_dosattr = TRUE;
+ set_dosattr = true;
time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
(~ATTR_READONLY));
/* Windows ignores set to zero */
if (time_buf.Attributes == 0)
time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
- mode_to_acl(direntry->d_inode, full_path, mode);
-#endif
}
if (attrs->ia_valid & ATTR_ATIME) {
- set_time = TRUE;
+ set_time = true;
time_buf.LastAccessTime =
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
} else
time_buf.LastAccessTime = 0;
if (attrs->ia_valid & ATTR_MTIME) {
- set_time = TRUE;
+ set_time = true;
time_buf.LastWriteTime =
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
} else
server times */
if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
- set_time = TRUE;
+ set_time = true;
/* Although Samba throws this field away
it may be useful to Windows - but we do
not want to set ctime unless some other
rc = -EOPNOTSUPP;
if (rc == -EOPNOTSUPP) {
- int oplock = FALSE;
+ int oplock = 0;
__u16 netfid;
cFYI(1, ("calling SetFileInfo since SetPathInfo for "