mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 19:15:14 +00:00
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:
commit
2a212f6996
11 changed files with 171 additions and 129 deletions
|
@ -2,6 +2,11 @@ Version 1.53
|
||||||
------------
|
------------
|
||||||
DFS support added (Microsoft Distributed File System client support needed
|
DFS support added (Microsoft Distributed File System client support needed
|
||||||
for referrals which enable a hierarchical name space among servers).
|
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
|
Version 1.52
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -97,9 +97,6 @@ cifs_read_super(struct super_block *sb, void *data,
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct cifs_sb_info *cifs_sb;
|
struct cifs_sb_info *cifs_sb;
|
||||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
|
||||||
int len;
|
|
||||||
#endif
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* BB should we make this contingent on mount parm? */
|
/* 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
|
* complex operation (mount), and in case of fail
|
||||||
* just exit instead of doing mount and attempting
|
* just exit instead of doing mount and attempting
|
||||||
* undo it if this copy fails?*/
|
* undo it if this copy fails?*/
|
||||||
len = strlen(data);
|
if (data) {
|
||||||
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
|
int len = strlen(data);
|
||||||
if (cifs_sb->mountdata == NULL) {
|
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
|
||||||
kfree(sb->s_fs_info);
|
if (cifs_sb->mountdata == NULL) {
|
||||||
sb->s_fs_info = NULL;
|
kfree(sb->s_fs_info);
|
||||||
return -ENOMEM;
|
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
|
#endif
|
||||||
|
|
||||||
rc = cifs_mount(sb, cifs_sb, data, devname);
|
rc = cifs_mount(sb, cifs_sb, data, devname);
|
||||||
|
|
|
@ -333,7 +333,6 @@ struct cifsFileInfo {
|
||||||
bool messageMode:1; /* for pipes: message vs byte mode */
|
bool messageMode:1; /* for pipes: message vs byte mode */
|
||||||
atomic_t wrtPending; /* handle in use - defer close */
|
atomic_t wrtPending; /* handle in use - defer close */
|
||||||
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
||||||
char *search_resume_name; /* BB removeme BB */
|
|
||||||
struct cifs_search_info srch_inf;
|
struct cifs_search_info srch_inf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -626,7 +625,7 @@ GLOBAL_EXTERN atomic_t tcpSesAllocCount;
|
||||||
GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
|
GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
|
||||||
GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
|
GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
|
||||||
|
|
||||||
/* Various Debug counters to remove someday (BB) */
|
/* Various Debug counters */
|
||||||
GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
|
GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
|
||||||
#ifdef CONFIG_CIFS_STATS2
|
#ifdef CONFIG_CIFS_STATS2
|
||||||
GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
|
GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
|
||||||
|
|
|
@ -79,6 +79,19 @@
|
||||||
#define TRANS2_GET_DFS_REFERRAL 0x10
|
#define TRANS2_GET_DFS_REFERRAL 0x10
|
||||||
#define TRANS2_REPORT_DFS_INCOSISTENCY 0x11
|
#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 */
|
/* NT Transact subcommand codes */
|
||||||
#define NT_TRANSACT_CREATE 0x01
|
#define NT_TRANSACT_CREATE 0x01
|
||||||
#define NT_TRANSACT_IOCTL 0x02
|
#define NT_TRANSACT_IOCTL 0x02
|
||||||
|
@ -328,12 +341,13 @@
|
||||||
#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
|
#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
|
||||||
#define CREATE_NO_EA_KNOWLEDGE 0x00000200
|
#define CREATE_NO_EA_KNOWLEDGE 0x00000200
|
||||||
#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
|
#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
|
||||||
open for recovery flag - should
|
"open for recovery" flag - should
|
||||||
be zero */
|
be zero in any case */
|
||||||
|
#define CREATE_OPEN_FOR_RECOVERY 0x00000400
|
||||||
#define CREATE_RANDOM_ACCESS 0x00000800
|
#define CREATE_RANDOM_ACCESS 0x00000800
|
||||||
#define CREATE_DELETE_ON_CLOSE 0x00001000
|
#define CREATE_DELETE_ON_CLOSE 0x00001000
|
||||||
#define CREATE_OPEN_BY_ID 0x00002000
|
#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_NO_COMPRESSION 0x00008000
|
||||||
#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
|
#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
|
||||||
#define OPEN_REPARSE_POINT 0x00200000
|
#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_AUTO_REINT 0x0004
|
||||||
#define SMB_CSC_CACHE_VDO 0x0008
|
#define SMB_CSC_CACHE_VDO 0x0008
|
||||||
#define SMB_CSC_NO_CACHING 0x000C
|
#define SMB_CSC_NO_CACHING 0x000C
|
||||||
|
|
||||||
#define SMB_UNIQUE_FILE_NAME 0x0010
|
#define SMB_UNIQUE_FILE_NAME 0x0010
|
||||||
#define SMB_EXTENDED_SIGNATURES 0x0020
|
#define SMB_EXTENDED_SIGNATURES 0x0020
|
||||||
|
|
||||||
|
@ -806,7 +819,7 @@ typedef struct smb_com_findclose_req {
|
||||||
#define ICOUNT_MASK 0x00FF
|
#define ICOUNT_MASK 0x00FF
|
||||||
#define PIPE_READ_MODE 0x0100
|
#define PIPE_READ_MODE 0x0100
|
||||||
#define NAMED_PIPE_TYPE 0x0400
|
#define NAMED_PIPE_TYPE 0x0400
|
||||||
#define PIPE_END_POINT 0x0800
|
#define PIPE_END_POINT 0x4000
|
||||||
#define BLOCKING_NAMED_PIPE 0x8000
|
#define BLOCKING_NAMED_PIPE 0x8000
|
||||||
|
|
||||||
typedef struct smb_com_open_req { /* also handles create */
|
typedef struct smb_com_open_req { /* also handles create */
|
||||||
|
|
|
@ -1728,7 +1728,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
LOCK_REQ *pSMB = NULL;
|
LOCK_REQ *pSMB = NULL;
|
||||||
LOCK_RSP *pSMBr = NULL;
|
/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
|
||||||
int bytes_returned;
|
int bytes_returned;
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
__u16 count;
|
__u16 count;
|
||||||
|
@ -1739,8 +1739,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
|
|
||||||
|
|
||||||
if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
|
if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
|
||||||
timeout = CIFS_ASYNC_OP; /* no response expected */
|
timeout = CIFS_ASYNC_OP; /* no response expected */
|
||||||
pSMB->Timeout = 0;
|
pSMB->Timeout = 0;
|
||||||
|
@ -1774,7 +1772,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
|
|
||||||
if (waitFlag) {
|
if (waitFlag) {
|
||||||
rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
|
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);
|
cifs_small_buf_release(pSMB);
|
||||||
} else {
|
} else {
|
||||||
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
|
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
|
||||||
|
|
|
@ -653,6 +653,7 @@ multi_t2_fnd:
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&GlobalMid_Lock);
|
||||||
server->tcpStatus = CifsExiting;
|
server->tcpStatus = CifsExiting;
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&GlobalMid_Lock);
|
||||||
|
wake_up_all(&server->response_q);
|
||||||
|
|
||||||
/* don't exit until kthread_stop is called */
|
/* don't exit until kthread_stop is called */
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
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;
|
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 =
|
tcon =
|
||||||
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
|
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
|
||||||
volume_info.username);
|
volume_info.username);
|
||||||
|
|
|
@ -260,7 +260,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||||
buf, inode->i_sb, xid,
|
buf, inode->i_sb, xid,
|
||||||
&fileHandle);
|
&fileHandle);
|
||||||
if (newinode) {
|
if (newinode) {
|
||||||
newinode->i_mode = mode;
|
if (cifs_sb->mnt_cifs_flags &
|
||||||
|
CIFS_MOUNT_DYNPERM)
|
||||||
|
newinode->i_mode = mode;
|
||||||
if ((oplock & CIFS_CREATE_ACTION) &&
|
if ((oplock & CIFS_CREATE_ACTION) &&
|
||||||
(cifs_sb->mnt_cifs_flags &
|
(cifs_sb->mnt_cifs_flags &
|
||||||
CIFS_MOUNT_SET_UID)) {
|
CIFS_MOUNT_SET_UID)) {
|
||||||
|
|
|
@ -546,7 +546,6 @@ int cifs_close(struct inode *inode, struct file *file)
|
||||||
msleep(timeout);
|
msleep(timeout);
|
||||||
timeout *= 8;
|
timeout *= 8;
|
||||||
}
|
}
|
||||||
kfree(pSMBFile->search_resume_name);
|
|
||||||
kfree(file->private_data);
|
kfree(file->private_data);
|
||||||
file->private_data = NULL;
|
file->private_data = NULL;
|
||||||
} else
|
} else
|
||||||
|
@ -605,12 +604,6 @@ int cifs_closedir(struct inode *inode, struct file *file)
|
||||||
else
|
else
|
||||||
cifs_buf_release(ptmp);
|
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);
|
kfree(file->private_data);
|
||||||
file->private_data = NULL;
|
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;
|
char *buf = NULL;
|
||||||
bool adjustTZ = false;
|
bool adjustTZ = false;
|
||||||
bool is_dfs_referral = false;
|
bool is_dfs_referral = false;
|
||||||
|
umode_t default_mode;
|
||||||
|
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
cFYI(1, ("Getting info on %s", full_path));
|
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;
|
inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set default mode. will override for dirs below */
|
/* get default inode mode */
|
||||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
if (attr & ATTR_DIRECTORY)
|
||||||
/* new inode, can safely set these fields */
|
default_mode = cifs_sb->mnt_dir_mode;
|
||||||
inode->i_mode = cifs_sb->mnt_file_mode;
|
else
|
||||||
else /* since we set the inode type below we need to mask off
|
default_mode = cifs_sb->mnt_file_mode;
|
||||||
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"));
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
inode->i_mode |= S_IFREG;
|
if (attr & ATTR_DIRECTORY)
|
||||||
/* treat dos attribute of read-only as read-only mode eg 555 */
|
inode->i_mode |= S_IFDIR;
|
||||||
if (cifsInfo->cifsAttrs & ATTR_READONLY)
|
else
|
||||||
inode->i_mode &= ~(S_IWUGO);
|
inode->i_mode |= S_IFREG;
|
||||||
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? */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
|
@ -1019,8 +1015,11 @@ mkdir_get_info:
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
}
|
}
|
||||||
if (direntry->d_inode) {
|
if (direntry->d_inode) {
|
||||||
direntry->d_inode->i_mode = mode;
|
if (cifs_sb->mnt_cifs_flags &
|
||||||
direntry->d_inode->i_mode |= S_IFDIR;
|
CIFS_MOUNT_DYNPERM)
|
||||||
|
direntry->d_inode->i_mode =
|
||||||
|
(mode | S_IFDIR);
|
||||||
|
|
||||||
if (cifs_sb->mnt_cifs_flags &
|
if (cifs_sb->mnt_cifs_flags &
|
||||||
CIFS_MOUNT_SET_UID) {
|
CIFS_MOUNT_SET_UID) {
|
||||||
direntry->d_inode->i_uid =
|
direntry->d_inode->i_uid =
|
||||||
|
@ -1547,13 +1546,26 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
} else
|
} else
|
||||||
goto cifs_setattr_exit;
|
goto cifs_setattr_exit;
|
||||||
}
|
}
|
||||||
if (attrs->ia_valid & ATTR_UID) {
|
|
||||||
cFYI(1, ("UID changed to %d", attrs->ia_uid));
|
/*
|
||||||
uid = attrs->ia_uid;
|
* Without unix extensions we can't send ownership changes to the
|
||||||
}
|
* server, so silently ignore them. This is consistent with how
|
||||||
if (attrs->ia_valid & ATTR_GID) {
|
* local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
|
||||||
cFYI(1, ("GID changed to %d", attrs->ia_gid));
|
* CIFSACL support + proper Windows to Unix idmapping, we may be
|
||||||
gid = attrs->ia_gid;
|
* 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;
|
time_buf.Attributes = 0;
|
||||||
|
@ -1563,7 +1575,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
attrs->ia_valid &= ~ATTR_MODE;
|
attrs->ia_valid &= ~ATTR_MODE;
|
||||||
|
|
||||||
if (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;
|
mode = attrs->ia_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1578,18 +1590,18 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||||
rc = mode_to_acl(inode, full_path, mode);
|
rc = mode_to_acl(inode, full_path, mode);
|
||||||
else if ((mode & S_IWUGO) == 0) {
|
else
|
||||||
#else
|
|
||||||
if ((mode & S_IWUGO) == 0) {
|
|
||||||
#endif
|
#endif
|
||||||
/* not writeable */
|
if (((mode & S_IWUGO) == 0) &&
|
||||||
if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
|
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
|
||||||
set_dosattr = true;
|
set_dosattr = true;
|
||||||
time_buf.Attributes =
|
time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs |
|
||||||
cpu_to_le32(cifsInode->cifsAttrs |
|
ATTR_READONLY);
|
||||||
ATTR_READONLY);
|
/* fix up mode if we're not using dynperm */
|
||||||
}
|
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
|
||||||
} else if (cifsInode->cifsAttrs & ATTR_READONLY) {
|
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
|
/* If file is readonly on server, we would
|
||||||
not be able to write to it - so if any write
|
not be able to write to it - so if any write
|
||||||
bit is enabled for user or group or other we
|
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 */
|
/* Windows ignores set to zero */
|
||||||
if (time_buf.Attributes == 0)
|
if (time_buf.Attributes == 0)
|
||||||
time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
|
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 *)
|
pnotify = (struct file_notify_information *)
|
||||||
((char *)&pSMBr->hdr.Protocol + data_offset);
|
((char *)&pSMBr->hdr.Protocol + data_offset);
|
||||||
cFYI(1, ("dnotify on %s Action: 0x%x",
|
cFYI(1, ("dnotify on %s Action: 0x%x",
|
||||||
pnotify->FileName,
|
pnotify->FileName, pnotify->Action));
|
||||||
pnotify->Action)); /* BB removeme BB */
|
|
||||||
/* cifs_dump_mem("Rcvd notify Data: ",buf,
|
/* cifs_dump_mem("Rcvd notify Data: ",buf,
|
||||||
sizeof(struct smb_hdr)+60); */
|
sizeof(struct smb_hdr)+60); */
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -132,6 +132,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
||||||
__u32 attr;
|
__u32 attr;
|
||||||
__u64 allocation_size;
|
__u64 allocation_size;
|
||||||
__u64 end_of_file;
|
__u64 end_of_file;
|
||||||
|
umode_t default_mode;
|
||||||
|
|
||||||
/* save mtime and size */
|
/* save mtime and size */
|
||||||
local_mtime = tmp_inode->i_mtime;
|
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) {
|
if (atomic_read(&cifsInfo->inUse) == 0) {
|
||||||
tmp_inode->i_uid = cifs_sb->mnt_uid;
|
tmp_inode->i_uid = cifs_sb->mnt_uid;
|
||||||
tmp_inode->i_gid = cifs_sb->mnt_gid;
|
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 {
|
if (attr & ATTR_DIRECTORY)
|
||||||
/* mask off the type bits since it gets set
|
default_mode = cifs_sb->mnt_dir_mode;
|
||||||
below and we do not want to get two type
|
else
|
||||||
bits set */
|
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;
|
tmp_inode->i_mode &= ~S_IFMT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr & ATTR_DIRECTORY) {
|
/* clear write bits if ATTR_READONLY is set */
|
||||||
*pobject_type = DT_DIR;
|
if (attr & ATTR_READONLY)
|
||||||
/* override default perms since we do not lock dirs */
|
tmp_inode->i_mode &= ~S_IWUGO;
|
||||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
|
||||||
tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
|
/* set inode type */
|
||||||
tmp_inode->i_mode |= S_IFDIR;
|
if ((attr & ATTR_SYSTEM) &&
|
||||||
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
|
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
|
||||||
(attr & ATTR_SYSTEM)) {
|
|
||||||
if (end_of_file == 0) {
|
if (end_of_file == 0) {
|
||||||
*pobject_type = DT_FIFO;
|
|
||||||
tmp_inode->i_mode |= S_IFIFO;
|
tmp_inode->i_mode |= S_IFIFO;
|
||||||
|
*pobject_type = DT_FIFO;
|
||||||
} else {
|
} else {
|
||||||
/* rather than get the type here, we mark the
|
/*
|
||||||
inode as needing revalidate and get the real type
|
* trying to get the type can be slow, so just call
|
||||||
(blk vs chr vs. symlink) later ie in lookup */
|
* this a regular file for now, and mark for reval
|
||||||
*pobject_type = DT_REG;
|
*/
|
||||||
tmp_inode->i_mode |= S_IFREG;
|
tmp_inode->i_mode |= S_IFREG;
|
||||||
|
*pobject_type = DT_REG;
|
||||||
cifsInfo->time = 0;
|
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 {
|
} else {
|
||||||
*pobject_type = DT_REG;
|
if (attr & ATTR_DIRECTORY) {
|
||||||
tmp_inode->i_mode |= S_IFREG;
|
tmp_inode->i_mode |= S_IFDIR;
|
||||||
if (attr & ATTR_READONLY)
|
*pobject_type = DT_DIR;
|
||||||
tmp_inode->i_mode &= ~(S_IWUGO);
|
} else {
|
||||||
else if ((tmp_inode->i_mode & S_IWUGO) == 0)
|
tmp_inode->i_mode |= S_IFREG;
|
||||||
/* the ATTR_READONLY flag may have been changed on */
|
*pobject_type = DT_REG;
|
||||||
/* 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? */
|
|
||||||
|
|
||||||
/* can not fill in nlink here as in qpathinfo version and Unx search */
|
/* can not fill in nlink here as in qpathinfo version and Unx search */
|
||||||
if (atomic_read(&cifsInfo->inUse) == 0)
|
if (atomic_read(&cifsInfo->inUse) == 0)
|
||||||
|
@ -675,8 +682,6 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
||||||
cifsFile->invalidHandle = true;
|
cifsFile->invalidHandle = true;
|
||||||
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
||||||
}
|
}
|
||||||
kfree(cifsFile->search_resume_name);
|
|
||||||
cifsFile->search_resume_name = NULL;
|
|
||||||
if (cifsFile->srch_inf.ntwrk_buf_start) {
|
if (cifsFile->srch_inf.ntwrk_buf_start) {
|
||||||
cFYI(1, ("freeing SMB ff cache buf on search rewind"));
|
cFYI(1, ("freeing SMB ff cache buf on search rewind"));
|
||||||
if (cifsFile->srch_inf.smallBuf)
|
if (cifsFile->srch_inf.smallBuf)
|
||||||
|
@ -1043,9 +1048,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
||||||
} /* else {
|
} /* else {
|
||||||
cifsFile->invalidHandle = true;
|
cifsFile->invalidHandle = true;
|
||||||
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
CIFSFindClose(xid, pTcon, cifsFile->netfid);
|
||||||
}
|
} */
|
||||||
kfree(cifsFile->search_resume_name);
|
|
||||||
cifsFile->search_resume_name = NULL; */
|
|
||||||
|
|
||||||
rc = find_cifs_entry(xid, pTcon, file,
|
rc = find_cifs_entry(xid, pTcon, file,
|
||||||
¤t_entry, &num_to_fill);
|
¤t_entry, &num_to_fill);
|
||||||
|
|
Loading…
Add table
Reference in a new issue