Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] cifs: fix oops on mount when CONFIG_CIFS_DFS_UPCALL is enabled [CIFS] Fix hang in mount when negprot causes server to kill tcp session disable most mode changes on non-unix/non-cifsacl mounts [CIFS] Correct incorrect obscure open flag [CIFS] warn if both dynperm and cifsacl mount options specified silently ignore ownership changes unless unix extensions are enabled or we're faking uid changes [CIFS] remove trailing whitespace when creating new inodes, use file_mode/dir_mode exclusively on mount without unix extensions on non-posix shares, clear write bits in mode when ATTR_READONLY is set [CIFS] remove unused variables
This commit is contained in:
Коммит
2a212f6996
|
@ -2,6 +2,11 @@ Version 1.53
|
|||
------------
|
||||
DFS support added (Microsoft Distributed File System client support needed
|
||||
for referrals which enable a hierarchical name space among servers).
|
||||
Disable temporary caching of mode bits to servers which do not support
|
||||
storing of mode (e.g. Windows servers, when client mounts without cifsacl
|
||||
mount option) and add new "dynperm" mount option to enable temporary caching
|
||||
of mode (enable old behavior). Fix hang on mount caused when server crashes
|
||||
tcp session during negotiate protocol.
|
||||
|
||||
Version 1.52
|
||||
------------
|
||||
|
|
|
@ -97,9 +97,6 @@ cifs_read_super(struct super_block *sb, void *data,
|
|||
{
|
||||
struct inode *inode;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
int len;
|
||||
#endif
|
||||
int rc = 0;
|
||||
|
||||
/* BB should we make this contingent on mount parm? */
|
||||
|
@ -117,15 +114,17 @@ cifs_read_super(struct super_block *sb, void *data,
|
|||
* complex operation (mount), and in case of fail
|
||||
* just exit instead of doing mount and attempting
|
||||
* undo it if this copy fails?*/
|
||||
len = strlen(data);
|
||||
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
|
||||
if (cifs_sb->mountdata == NULL) {
|
||||
kfree(sb->s_fs_info);
|
||||
sb->s_fs_info = NULL;
|
||||
return -ENOMEM;
|
||||
if (data) {
|
||||
int len = strlen(data);
|
||||
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
|
||||
if (cifs_sb->mountdata == NULL) {
|
||||
kfree(sb->s_fs_info);
|
||||
sb->s_fs_info = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
strncpy(cifs_sb->mountdata, data, len + 1);
|
||||
cifs_sb->mountdata[len] = '\0';
|
||||
}
|
||||
strncpy(cifs_sb->mountdata, data, len + 1);
|
||||
cifs_sb->mountdata[len] = '\0';
|
||||
#endif
|
||||
|
||||
rc = cifs_mount(sb, cifs_sb, data, devname);
|
||||
|
|
|
@ -333,7 +333,6 @@ struct cifsFileInfo {
|
|||
bool messageMode:1; /* for pipes: message vs byte mode */
|
||||
atomic_t wrtPending; /* handle in use - defer close */
|
||||
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
||||
char *search_resume_name; /* BB removeme BB */
|
||||
struct cifs_search_info srch_inf;
|
||||
};
|
||||
|
||||
|
@ -626,7 +625,7 @@ GLOBAL_EXTERN atomic_t tcpSesAllocCount;
|
|||
GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
|
||||
GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
|
||||
|
||||
/* Various Debug counters to remove someday (BB) */
|
||||
/* Various Debug counters */
|
||||
GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
|
||||
|
|
|
@ -79,6 +79,19 @@
|
|||
#define TRANS2_GET_DFS_REFERRAL 0x10
|
||||
#define TRANS2_REPORT_DFS_INCOSISTENCY 0x11
|
||||
|
||||
/* SMB Transact (Named Pipe) subcommand codes */
|
||||
#define TRANS_SET_NMPIPE_STATE 0x0001
|
||||
#define TRANS_RAW_READ_NMPIPE 0x0011
|
||||
#define TRANS_QUERY_NMPIPE_STATE 0x0021
|
||||
#define TRANS_QUERY_NMPIPE_INFO 0x0022
|
||||
#define TRANS_PEEK_NMPIPE 0x0023
|
||||
#define TRANS_TRANSACT_NMPIPE 0x0026
|
||||
#define TRANS_RAW_WRITE_NMPIPE 0x0031
|
||||
#define TRANS_READ_NMPIPE 0x0036
|
||||
#define TRANS_WRITE_NMPIPE 0x0037
|
||||
#define TRANS_WAIT_NMPIPE 0x0053
|
||||
#define TRANS_CALL_NMPIPE 0x0054
|
||||
|
||||
/* NT Transact subcommand codes */
|
||||
#define NT_TRANSACT_CREATE 0x01
|
||||
#define NT_TRANSACT_IOCTL 0x02
|
||||
|
@ -328,12 +341,13 @@
|
|||
#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
|
||||
#define CREATE_NO_EA_KNOWLEDGE 0x00000200
|
||||
#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
|
||||
open for recovery flag - should
|
||||
be zero */
|
||||
"open for recovery" flag - should
|
||||
be zero in any case */
|
||||
#define CREATE_OPEN_FOR_RECOVERY 0x00000400
|
||||
#define CREATE_RANDOM_ACCESS 0x00000800
|
||||
#define CREATE_DELETE_ON_CLOSE 0x00001000
|
||||
#define CREATE_OPEN_BY_ID 0x00002000
|
||||
#define CREATE_OPEN_BACKUP_INTN 0x00004000
|
||||
#define CREATE_OPEN_BACKUP_INTENT 0x00004000
|
||||
#define CREATE_NO_COMPRESSION 0x00008000
|
||||
#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
|
||||
#define OPEN_REPARSE_POINT 0x00200000
|
||||
|
@ -722,7 +736,6 @@ typedef struct smb_com_tconx_rsp_ext {
|
|||
#define SMB_CSC_CACHE_AUTO_REINT 0x0004
|
||||
#define SMB_CSC_CACHE_VDO 0x0008
|
||||
#define SMB_CSC_NO_CACHING 0x000C
|
||||
|
||||
#define SMB_UNIQUE_FILE_NAME 0x0010
|
||||
#define SMB_EXTENDED_SIGNATURES 0x0020
|
||||
|
||||
|
@ -806,7 +819,7 @@ typedef struct smb_com_findclose_req {
|
|||
#define ICOUNT_MASK 0x00FF
|
||||
#define PIPE_READ_MODE 0x0100
|
||||
#define NAMED_PIPE_TYPE 0x0400
|
||||
#define PIPE_END_POINT 0x0800
|
||||
#define PIPE_END_POINT 0x4000
|
||||
#define BLOCKING_NAMED_PIPE 0x8000
|
||||
|
||||
typedef struct smb_com_open_req { /* also handles create */
|
||||
|
|
|
@ -1728,7 +1728,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||
{
|
||||
int rc = 0;
|
||||
LOCK_REQ *pSMB = NULL;
|
||||
LOCK_RSP *pSMBr = NULL;
|
||||
/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
|
||||
int bytes_returned;
|
||||
int timeout = 0;
|
||||
__u16 count;
|
||||
|
@ -1739,8 +1739,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
|
||||
|
||||
if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
|
||||
timeout = CIFS_ASYNC_OP; /* no response expected */
|
||||
pSMB->Timeout = 0;
|
||||
|
@ -1774,7 +1772,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||
|
||||
if (waitFlag) {
|
||||
rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned);
|
||||
(struct smb_hdr *) pSMB, &bytes_returned);
|
||||
cifs_small_buf_release(pSMB);
|
||||
} else {
|
||||
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
|
||||
|
|
|
@ -653,6 +653,7 @@ multi_t2_fnd:
|
|||
spin_lock(&GlobalMid_Lock);
|
||||
server->tcpStatus = CifsExiting;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
wake_up_all(&server->response_q);
|
||||
|
||||
/* don't exit until kthread_stop is called */
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
|
@ -2120,6 +2121,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
|||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
|
||||
}
|
||||
|
||||
if ((volume_info.cifs_acl) && (volume_info.dynperm))
|
||||
cERROR(1, ("mount option dynperm ignored if cifsacl "
|
||||
"mount option supported"));
|
||||
|
||||
tcon =
|
||||
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
|
||||
volume_info.username);
|
||||
|
|
|
@ -260,7 +260,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||
buf, inode->i_sb, xid,
|
||||
&fileHandle);
|
||||
if (newinode) {
|
||||
newinode->i_mode = mode;
|
||||
if (cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_DYNPERM)
|
||||
newinode->i_mode = mode;
|
||||
if ((oplock & CIFS_CREATE_ACTION) &&
|
||||
(cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID)) {
|
||||
|
|
|
@ -546,7 +546,6 @@ int cifs_close(struct inode *inode, struct file *file)
|
|||
msleep(timeout);
|
||||
timeout *= 8;
|
||||
}
|
||||
kfree(pSMBFile->search_resume_name);
|
||||
kfree(file->private_data);
|
||||
file->private_data = NULL;
|
||||
} else
|
||||
|
@ -605,12 +604,6 @@ int cifs_closedir(struct inode *inode, struct file *file)
|
|||
else
|
||||
cifs_buf_release(ptmp);
|
||||
}
|
||||
ptmp = pCFileStruct->search_resume_name;
|
||||
if (ptmp) {
|
||||
cFYI(1, ("closedir free resume name"));
|
||||
pCFileStruct->search_resume_name = NULL;
|
||||
kfree(ptmp);
|
||||
}
|
||||
kfree(file->private_data);
|
||||
file->private_data = NULL;
|
||||
}
|
||||
|
|
146
fs/cifs/inode.c
146
fs/cifs/inode.c
|
@ -418,6 +418,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
char *buf = NULL;
|
||||
bool adjustTZ = false;
|
||||
bool is_dfs_referral = false;
|
||||
umode_t default_mode;
|
||||
|
||||
pTcon = cifs_sb->tcon;
|
||||
cFYI(1, ("Getting info on %s", full_path));
|
||||
|
@ -530,47 +531,42 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
|
||||
}
|
||||
|
||||
/* set default mode. will override for dirs below */
|
||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
||||
/* new inode, can safely set these fields */
|
||||
inode->i_mode = cifs_sb->mnt_file_mode;
|
||||
else /* since we set the inode type below we need to mask off
|
||||
to avoid strange results if type changes and both
|
||||
get orred in */
|
||||
inode->i_mode &= ~S_IFMT;
|
||||
/* if (attr & ATTR_REPARSE) */
|
||||
/* We no longer handle these as symlinks because we could not
|
||||
follow them due to the absolute path with drive letter */
|
||||
if (attr & ATTR_DIRECTORY) {
|
||||
/* override default perms since we do not do byte range locking
|
||||
on dirs */
|
||||
inode->i_mode = cifs_sb->mnt_dir_mode;
|
||||
inode->i_mode |= S_IFDIR;
|
||||
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
|
||||
(cifsInfo->cifsAttrs & ATTR_SYSTEM) &&
|
||||
/* No need to le64 convert size of zero */
|
||||
(pfindData->EndOfFile == 0)) {
|
||||
inode->i_mode = cifs_sb->mnt_file_mode;
|
||||
inode->i_mode |= S_IFIFO;
|
||||
/* BB Finish for SFU style symlinks and devices */
|
||||
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
|
||||
(cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
|
||||
if (decode_sfu_inode(inode, le64_to_cpu(pfindData->EndOfFile),
|
||||
full_path, cifs_sb, xid))
|
||||
cFYI(1, ("Unrecognized sfu inode type"));
|
||||
/* get default inode mode */
|
||||
if (attr & ATTR_DIRECTORY)
|
||||
default_mode = cifs_sb->mnt_dir_mode;
|
||||
else
|
||||
default_mode = cifs_sb->mnt_file_mode;
|
||||
|
||||
cFYI(1, ("sfu mode 0%o", inode->i_mode));
|
||||
/* set permission bits */
|
||||
if (atomic_read(&cifsInfo->inUse) == 0 ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
|
||||
inode->i_mode = default_mode;
|
||||
else {
|
||||
/* just reenable write bits if !ATTR_READONLY */
|
||||
if ((inode->i_mode & S_IWUGO) == 0 &&
|
||||
(attr & ATTR_READONLY) == 0)
|
||||
inode->i_mode |= (S_IWUGO & default_mode);
|
||||
inode->i_mode &= ~S_IFMT;
|
||||
}
|
||||
/* clear write bits if ATTR_READONLY is set */
|
||||
if (attr & ATTR_READONLY)
|
||||
inode->i_mode &= ~S_IWUGO;
|
||||
|
||||
/* set inode type */
|
||||
if ((attr & ATTR_SYSTEM) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
|
||||
/* no need to fix endianness on 0 */
|
||||
if (pfindData->EndOfFile == 0)
|
||||
inode->i_mode |= S_IFIFO;
|
||||
else if (decode_sfu_inode(inode,
|
||||
le64_to_cpu(pfindData->EndOfFile),
|
||||
full_path, cifs_sb, xid))
|
||||
cFYI(1, ("unknown SFU file type\n"));
|
||||
} else {
|
||||
inode->i_mode |= S_IFREG;
|
||||
/* treat dos attribute of read-only as read-only mode eg 555 */
|
||||
if (cifsInfo->cifsAttrs & ATTR_READONLY)
|
||||
inode->i_mode &= ~(S_IWUGO);
|
||||
else if ((inode->i_mode & S_IWUGO) == 0)
|
||||
/* the ATTR_READONLY flag may have been */
|
||||
/* changed on server -- set any w bits */
|
||||
/* allowed by mnt_file_mode */
|
||||
inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
|
||||
/* BB add code to validate if device or weird share or device type? */
|
||||
if (attr & ATTR_DIRECTORY)
|
||||
inode->i_mode |= S_IFDIR;
|
||||
else
|
||||
inode->i_mode |= S_IFREG;
|
||||
}
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
|
@ -1019,8 +1015,11 @@ mkdir_get_info:
|
|||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
if (direntry->d_inode) {
|
||||
direntry->d_inode->i_mode = mode;
|
||||
direntry->d_inode->i_mode |= S_IFDIR;
|
||||
if (cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_DYNPERM)
|
||||
direntry->d_inode->i_mode =
|
||||
(mode | S_IFDIR);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID) {
|
||||
direntry->d_inode->i_uid =
|
||||
|
@ -1547,13 +1546,26 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||
} else
|
||||
goto cifs_setattr_exit;
|
||||
}
|
||||
if (attrs->ia_valid & ATTR_UID) {
|
||||
cFYI(1, ("UID changed to %d", attrs->ia_uid));
|
||||
uid = attrs->ia_uid;
|
||||
}
|
||||
if (attrs->ia_valid & ATTR_GID) {
|
||||
cFYI(1, ("GID changed to %d", attrs->ia_gid));
|
||||
gid = attrs->ia_gid;
|
||||
|
||||
/*
|
||||
* Without unix extensions we can't send ownership changes to the
|
||||
* server, so silently ignore them. This is consistent with how
|
||||
* local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
|
||||
* CIFSACL support + proper Windows to Unix idmapping, we may be
|
||||
* able to support this in the future.
|
||||
*/
|
||||
if (!pTcon->unix_ext &&
|
||||
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
|
||||
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
|
||||
} else {
|
||||
if (attrs->ia_valid & ATTR_UID) {
|
||||
cFYI(1, ("UID changed to %d", attrs->ia_uid));
|
||||
uid = attrs->ia_uid;
|
||||
}
|
||||
if (attrs->ia_valid & ATTR_GID) {
|
||||
cFYI(1, ("GID changed to %d", attrs->ia_gid));
|
||||
gid = attrs->ia_gid;
|
||||
}
|
||||
}
|
||||
|
||||
time_buf.Attributes = 0;
|
||||
|
@ -1563,7 +1575,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||
attrs->ia_valid &= ~ATTR_MODE;
|
||||
|
||||
if (attrs->ia_valid & ATTR_MODE) {
|
||||
cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
|
||||
cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
|
||||
mode = attrs->ia_mode;
|
||||
}
|
||||
|
||||
|
@ -1578,18 +1590,18 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||
rc = mode_to_acl(inode, full_path, mode);
|
||||
else if ((mode & S_IWUGO) == 0) {
|
||||
#else
|
||||
if ((mode & S_IWUGO) == 0) {
|
||||
else
|
||||
#endif
|
||||
/* not writeable */
|
||||
if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
|
||||
set_dosattr = true;
|
||||
time_buf.Attributes =
|
||||
cpu_to_le32(cifsInode->cifsAttrs |
|
||||
ATTR_READONLY);
|
||||
}
|
||||
} else if (cifsInode->cifsAttrs & ATTR_READONLY) {
|
||||
if (((mode & S_IWUGO) == 0) &&
|
||||
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
|
||||
set_dosattr = true;
|
||||
time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs |
|
||||
ATTR_READONLY);
|
||||
/* fix up mode if we're not using dynperm */
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
|
||||
attrs->ia_mode = inode->i_mode & ~S_IWUGO;
|
||||
} else if ((mode & S_IWUGO) &&
|
||||
(cifsInode->cifsAttrs & ATTR_READONLY)) {
|
||||
/* If file is readonly on server, we would
|
||||
not be able to write to it - so if any write
|
||||
bit is enabled for user or group or other we
|
||||
|
@ -1600,6 +1612,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||
/* Windows ignores set to zero */
|
||||
if (time_buf.Attributes == 0)
|
||||
time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
|
||||
|
||||
/* reset local inode permissions to normal */
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
|
||||
attrs->ia_mode &= ~(S_IALLUGO);
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
attrs->ia_mode |=
|
||||
cifs_sb->mnt_dir_mode;
|
||||
else
|
||||
attrs->ia_mode |=
|
||||
cifs_sb->mnt_file_mode;
|
||||
}
|
||||
} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
|
||||
/* ignore mode change - ATTR_READONLY hasn't changed */
|
||||
attrs->ia_valid &= ~ATTR_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -519,8 +519,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
|
|||
pnotify = (struct file_notify_information *)
|
||||
((char *)&pSMBr->hdr.Protocol + data_offset);
|
||||
cFYI(1, ("dnotify on %s Action: 0x%x",
|
||||
pnotify->FileName,
|
||||
pnotify->Action)); /* BB removeme BB */
|
||||
pnotify->FileName, pnotify->Action));
|
||||
/* cifs_dump_mem("Rcvd notify Data: ",buf,
|
||||
sizeof(struct smb_hdr)+60); */
|
||||
return true;
|
||||
|
|
|
@ -132,6 +132,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
|||
__u32 attr;
|
||||
__u64 allocation_size;
|
||||
__u64 end_of_file;
|
||||
umode_t default_mode;
|
||||
|
||||
/* save mtime and size */
|
||||
local_mtime = tmp_inode->i_mtime;
|
||||
|
@ -187,48 +188,54 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
|||
if (atomic_read(&cifsInfo->inUse) == 0) {
|
||||
tmp_inode->i_uid = cifs_sb->mnt_uid;
|
||||
tmp_inode->i_gid = cifs_sb->mnt_gid;
|
||||
/* set default mode. will override for dirs below */
|
||||
tmp_inode->i_mode = cifs_sb->mnt_file_mode;
|
||||
} else {
|
||||
/* mask off the type bits since it gets set
|
||||
below and we do not want to get two type
|
||||
bits set */
|
||||
}
|
||||
|
||||
if (attr & ATTR_DIRECTORY)
|
||||
default_mode = cifs_sb->mnt_dir_mode;
|
||||
else
|
||||
default_mode = cifs_sb->mnt_file_mode;
|
||||
|
||||
/* set initial permissions */
|
||||
if ((atomic_read(&cifsInfo->inUse) == 0) ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
|
||||
tmp_inode->i_mode = default_mode;
|
||||
else {
|
||||
/* just reenable write bits if !ATTR_READONLY */
|
||||
if ((tmp_inode->i_mode & S_IWUGO) == 0 &&
|
||||
(attr & ATTR_READONLY) == 0)
|
||||
tmp_inode->i_mode |= (S_IWUGO & default_mode);
|
||||
|
||||
tmp_inode->i_mode &= ~S_IFMT;
|
||||
}
|
||||
|
||||
if (attr & ATTR_DIRECTORY) {
|
||||
*pobject_type = DT_DIR;
|
||||
/* override default perms since we do not lock dirs */
|
||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
||||
tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
|
||||
tmp_inode->i_mode |= S_IFDIR;
|
||||
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
|
||||
(attr & ATTR_SYSTEM)) {
|
||||
/* clear write bits if ATTR_READONLY is set */
|
||||
if (attr & ATTR_READONLY)
|
||||
tmp_inode->i_mode &= ~S_IWUGO;
|
||||
|
||||
/* set inode type */
|
||||
if ((attr & ATTR_SYSTEM) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
|
||||
if (end_of_file == 0) {
|
||||
*pobject_type = DT_FIFO;
|
||||
tmp_inode->i_mode |= S_IFIFO;
|
||||
*pobject_type = DT_FIFO;
|
||||
} else {
|
||||
/* rather than get the type here, we mark the
|
||||
inode as needing revalidate and get the real type
|
||||
(blk vs chr vs. symlink) later ie in lookup */
|
||||
*pobject_type = DT_REG;
|
||||
/*
|
||||
* trying to get the type can be slow, so just call
|
||||
* this a regular file for now, and mark for reval
|
||||
*/
|
||||
tmp_inode->i_mode |= S_IFREG;
|
||||
*pobject_type = DT_REG;
|
||||
cifsInfo->time = 0;
|
||||
}
|
||||
/* we no longer mark these because we could not follow them */
|
||||
/* } else if (attr & ATTR_REPARSE) {
|
||||
*pobject_type = DT_LNK;
|
||||
tmp_inode->i_mode |= S_IFLNK; */
|
||||
} else {
|
||||
*pobject_type = DT_REG;
|
||||
tmp_inode->i_mode |= S_IFREG;
|
||||
if (attr & ATTR_READONLY)
|
||||
tmp_inode->i_mode &= ~(S_IWUGO);
|
||||
else if ((tmp_inode->i_mode & S_IWUGO) == 0)
|
||||
/* the ATTR_READONLY flag may have been changed on */
|
||||
/* server -- set any w bits allowed by mnt_file_mode */
|
||||
tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
|
||||
} /* could add code here - to validate if device or weird share type? */
|
||||
if (attr & ATTR_DIRECTORY) {
|
||||
tmp_inode->i_mode |= S_IFDIR;
|
||||
*pobject_type = DT_DIR;
|
||||
} else {
|
||||
tmp_inode->i_mode |= S_IFREG;
|
||||
*pobject_type = DT_REG;
|
||||
}
|
||||
}
|
||||
|
||||
/* can not fill in nlink here as in qpathinfo version and Unx search */
|
||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
||||
|
@ -675,8 +682,6 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
|||
cifsFile->invalidHandle = true;
|
||||
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
||||
}
|
||||
kfree(cifsFile->search_resume_name);
|
||||
cifsFile->search_resume_name = NULL;
|
||||
if (cifsFile->srch_inf.ntwrk_buf_start) {
|
||||
cFYI(1, ("freeing SMB ff cache buf on search rewind"));
|
||||
if (cifsFile->srch_inf.smallBuf)
|
||||
|
@ -1043,9 +1048,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||
} /* else {
|
||||
cifsFile->invalidHandle = true;
|
||||
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
||||
}
|
||||
kfree(cifsFile->search_resume_name);
|
||||
cifsFile->search_resume_name = NULL; */
|
||||
} */
|
||||
|
||||
rc = find_cifs_entry(xid, pTcon, file,
|
||||
¤t_entry, &num_to_fill);
|
||||
|
|
Загрузка…
Ссылка в новой задаче