mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 14:50:19 +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: remove bogus remapping of error in cifs_filldir() cifs: allow calling cifs_build_path_to_root on incomplete cifs_sb cifs: fix check of error return from is_path_accessable cifs: remove Local_System_Name cifs: fix use of CONFIG_CIFS_ACL cifs: add attribute cache timeout (actimeo) tunable
This commit is contained in:
commit
caa4a59574
@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
|
||||
cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
|
||||
link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
|
||||
md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
|
||||
readdir.o ioctl.o sess.o export.o cifsacl.o
|
||||
readdir.o ioctl.o sess.o export.o
|
||||
|
||||
cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
|
||||
|
||||
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
|
||||
|
||||
|
@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
|
||||
wsize default write size (default 57344)
|
||||
maximum wsize currently allowed by CIFS is 57344 (fourteen
|
||||
4096 byte pages)
|
||||
actimeo=n attribute cache timeout in seconds (default 1 second).
|
||||
After this timeout, the cifs client requests fresh attribute
|
||||
information from the server. This option allows to tune the
|
||||
attribute cache timeout to suit the workload needs. Shorter
|
||||
timeouts mean better the cache coherency, but increased number
|
||||
of calls to the server. Longer timeouts mean reduced number
|
||||
of calls to the server at the expense of less stricter cache
|
||||
coherency checks (i.e. incorrect attribute cache for a short
|
||||
period of time).
|
||||
rw mount the network share read-write (note that the
|
||||
server may still consider the share read-only)
|
||||
ro mount network share read-only
|
||||
|
@ -48,6 +48,7 @@ struct cifs_sb_info {
|
||||
struct nls_table *local_nls;
|
||||
unsigned int rsize;
|
||||
unsigned int wsize;
|
||||
unsigned long actimeo; /* attribute cache timeout (jiffies) */
|
||||
atomic_t active;
|
||||
uid_t mnt_uid;
|
||||
gid_t mnt_gid;
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "cifs_debug.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
|
||||
static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
|
||||
{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
|
||||
{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
|
||||
@ -774,4 +772,3 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
||||
|
@ -74,11 +74,7 @@ struct cifs_wksid {
|
||||
char sidname[SIDNAMELENGTH];
|
||||
} __attribute__((packed));
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
|
||||
extern int match_sid(struct cifs_sid *);
|
||||
extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
|
||||
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
||||
|
||||
#endif /* _CIFSACL_H */
|
||||
|
@ -463,6 +463,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
||||
|
||||
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
|
||||
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
|
||||
/* convert actimeo and display it in seconds */
|
||||
seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -935,7 +937,6 @@ init_cifs(void)
|
||||
GlobalCurrentXid = 0;
|
||||
GlobalTotalActiveXid = 0;
|
||||
GlobalMaxActiveXid = 0;
|
||||
memset(Local_System_Name, 0, 15);
|
||||
spin_lock_init(&cifs_tcp_ses_lock);
|
||||
spin_lock_init(&cifs_file_list_lock);
|
||||
spin_lock_init(&GlobalMid_Lock);
|
||||
|
@ -44,6 +44,16 @@
|
||||
|
||||
#define CIFS_MIN_RCV_POOL 4
|
||||
|
||||
/*
|
||||
* default attribute cache timeout (jiffies)
|
||||
*/
|
||||
#define CIFS_DEF_ACTIMEO (1 * HZ)
|
||||
|
||||
/*
|
||||
* max attribute cache timeout (jiffies) - 2^30
|
||||
*/
|
||||
#define CIFS_MAX_ACTIMEO (1 << 30)
|
||||
|
||||
/*
|
||||
* MAX_REQ is the maximum number of requests that WE will send
|
||||
* on one socket concurrently. It also matches the most common
|
||||
@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
|
||||
/* on midQ entries */
|
||||
GLOBAL_EXTERN char Local_System_Name[15];
|
||||
|
||||
/*
|
||||
* Global counters, updated atomically
|
||||
*/
|
||||
|
@ -54,7 +54,8 @@ do { \
|
||||
__func__, curr_xid, (int)rc); \
|
||||
} while (0)
|
||||
extern char *build_path_from_dentry(struct dentry *);
|
||||
extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
|
||||
extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
|
||||
struct cifsTconInfo *tcon);
|
||||
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
|
||||
extern char *cifs_compose_mount_options(const char *sb_mountdata,
|
||||
const char *fullpath, const struct dfs_info3_param *ref,
|
||||
@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
|
||||
struct TCP_Server_Info *);
|
||||
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
|
||||
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
||||
#endif
|
||||
extern unsigned int smbCalcSize(struct smb_hdr *ptr);
|
||||
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
|
||||
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
|
@ -2478,95 +2478,6 @@ querySymLinkRetry:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
/* Initialize NT TRANSACT SMB into small smb request buffer.
|
||||
This assumes that all NT TRANSACTS that we init here have
|
||||
total parm and data under about 400 bytes (to fit in small cifs
|
||||
buffer size), which is the case so far, it easily fits. NB:
|
||||
Setup words themselves and ByteCount
|
||||
MaxSetupCount (size of returned setup area) and
|
||||
MaxParameterCount (returned parms size) must be set by caller */
|
||||
static int
|
||||
smb_init_nttransact(const __u16 sub_command, const int setup_count,
|
||||
const int parm_len, struct cifsTconInfo *tcon,
|
||||
void **ret_buf)
|
||||
{
|
||||
int rc;
|
||||
__u32 temp_offset;
|
||||
struct smb_com_ntransact_req *pSMB;
|
||||
|
||||
rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
|
||||
(void **)&pSMB);
|
||||
if (rc)
|
||||
return rc;
|
||||
*ret_buf = (void *)pSMB;
|
||||
pSMB->Reserved = 0;
|
||||
pSMB->TotalParameterCount = cpu_to_le32(parm_len);
|
||||
pSMB->TotalDataCount = 0;
|
||||
pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
|
||||
MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
|
||||
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
||||
pSMB->DataCount = pSMB->TotalDataCount;
|
||||
temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
|
||||
(setup_count * 2) - 4 /* for rfc1001 length itself */;
|
||||
pSMB->ParameterOffset = cpu_to_le32(temp_offset);
|
||||
pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
|
||||
pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
|
||||
pSMB->SubCommand = cpu_to_le16(sub_command);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_ntransact(char *buf, char **ppparm, char **ppdata,
|
||||
__u32 *pparmlen, __u32 *pdatalen)
|
||||
{
|
||||
char *end_of_smb;
|
||||
__u32 data_count, data_offset, parm_count, parm_offset;
|
||||
struct smb_com_ntransact_rsp *pSMBr;
|
||||
|
||||
*pdatalen = 0;
|
||||
*pparmlen = 0;
|
||||
|
||||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
pSMBr = (struct smb_com_ntransact_rsp *)buf;
|
||||
|
||||
/* ByteCount was converted from little endian in SendReceive */
|
||||
end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
|
||||
(char *)&pSMBr->ByteCount;
|
||||
|
||||
data_offset = le32_to_cpu(pSMBr->DataOffset);
|
||||
data_count = le32_to_cpu(pSMBr->DataCount);
|
||||
parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
|
||||
parm_count = le32_to_cpu(pSMBr->ParameterCount);
|
||||
|
||||
*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
|
||||
*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
|
||||
|
||||
/* should we also check that parm and data areas do not overlap? */
|
||||
if (*ppparm > end_of_smb) {
|
||||
cFYI(1, "parms start after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (parm_count + *ppparm > end_of_smb) {
|
||||
cFYI(1, "parm end after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (*ppdata > end_of_smb) {
|
||||
cFYI(1, "data starts after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (data_count + *ppdata > end_of_smb) {
|
||||
cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
|
||||
*ppdata, data_count, (data_count + *ppdata),
|
||||
end_of_smb, pSMBr);
|
||||
return -EINVAL;
|
||||
} else if (parm_count + data_count > pSMBr->ByteCount) {
|
||||
cFYI(1, "parm count and data count larger than SMB");
|
||||
return -EINVAL;
|
||||
}
|
||||
*pdatalen = data_count;
|
||||
*pparmlen = parm_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
@ -3056,7 +2967,97 @@ GetExtAttrOut:
|
||||
|
||||
#endif /* CONFIG_POSIX */
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
#ifdef CONFIG_CIFS_ACL
|
||||
/*
|
||||
* Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
|
||||
* all NT TRANSACTS that we init here have total parm and data under about 400
|
||||
* bytes (to fit in small cifs buffer size), which is the case so far, it
|
||||
* easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
|
||||
* returned setup area) and MaxParameterCount (returned parms size) must be set
|
||||
* by caller
|
||||
*/
|
||||
static int
|
||||
smb_init_nttransact(const __u16 sub_command, const int setup_count,
|
||||
const int parm_len, struct cifsTconInfo *tcon,
|
||||
void **ret_buf)
|
||||
{
|
||||
int rc;
|
||||
__u32 temp_offset;
|
||||
struct smb_com_ntransact_req *pSMB;
|
||||
|
||||
rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
|
||||
(void **)&pSMB);
|
||||
if (rc)
|
||||
return rc;
|
||||
*ret_buf = (void *)pSMB;
|
||||
pSMB->Reserved = 0;
|
||||
pSMB->TotalParameterCount = cpu_to_le32(parm_len);
|
||||
pSMB->TotalDataCount = 0;
|
||||
pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
|
||||
MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
|
||||
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
||||
pSMB->DataCount = pSMB->TotalDataCount;
|
||||
temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
|
||||
(setup_count * 2) - 4 /* for rfc1001 length itself */;
|
||||
pSMB->ParameterOffset = cpu_to_le32(temp_offset);
|
||||
pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
|
||||
pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
|
||||
pSMB->SubCommand = cpu_to_le16(sub_command);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_ntransact(char *buf, char **ppparm, char **ppdata,
|
||||
__u32 *pparmlen, __u32 *pdatalen)
|
||||
{
|
||||
char *end_of_smb;
|
||||
__u32 data_count, data_offset, parm_count, parm_offset;
|
||||
struct smb_com_ntransact_rsp *pSMBr;
|
||||
|
||||
*pdatalen = 0;
|
||||
*pparmlen = 0;
|
||||
|
||||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
pSMBr = (struct smb_com_ntransact_rsp *)buf;
|
||||
|
||||
/* ByteCount was converted from little endian in SendReceive */
|
||||
end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
|
||||
(char *)&pSMBr->ByteCount;
|
||||
|
||||
data_offset = le32_to_cpu(pSMBr->DataOffset);
|
||||
data_count = le32_to_cpu(pSMBr->DataCount);
|
||||
parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
|
||||
parm_count = le32_to_cpu(pSMBr->ParameterCount);
|
||||
|
||||
*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
|
||||
*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
|
||||
|
||||
/* should we also check that parm and data areas do not overlap? */
|
||||
if (*ppparm > end_of_smb) {
|
||||
cFYI(1, "parms start after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (parm_count + *ppparm > end_of_smb) {
|
||||
cFYI(1, "parm end after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (*ppdata > end_of_smb) {
|
||||
cFYI(1, "data starts after end of smb");
|
||||
return -EINVAL;
|
||||
} else if (data_count + *ppdata > end_of_smb) {
|
||||
cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
|
||||
*ppdata, data_count, (data_count + *ppdata),
|
||||
end_of_smb, pSMBr);
|
||||
return -EINVAL;
|
||||
} else if (parm_count + data_count > pSMBr->ByteCount) {
|
||||
cFYI(1, "parm count and data count larger than SMB");
|
||||
return -EINVAL;
|
||||
}
|
||||
*pdatalen = data_count;
|
||||
*pparmlen = parm_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get Security Descriptor (by handle) from remote server for a file or dir */
|
||||
int
|
||||
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
|
||||
@ -3214,7 +3215,7 @@ setCifsAclRetry:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
||||
#endif /* CONFIG_CIFS_ACL */
|
||||
|
||||
/* Legacy Query Path Information call for lookup to old servers such
|
||||
as Win9x/WinME */
|
||||
|
@ -105,6 +105,7 @@ struct smb_vol {
|
||||
unsigned int wsize;
|
||||
bool sockopt_tcp_nodelay:1;
|
||||
unsigned short int port;
|
||||
unsigned long actimeo; /* attribute cache timeout (jiffies) */
|
||||
char *prepath;
|
||||
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
|
||||
struct nls_table *local_nls;
|
||||
@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname,
|
||||
short int override_gid = -1;
|
||||
bool uid_specified = false;
|
||||
bool gid_specified = false;
|
||||
char *nodename = utsname()->nodename;
|
||||
|
||||
separator[0] = ',';
|
||||
separator[1] = 0;
|
||||
|
||||
if (Local_System_Name[0] != 0)
|
||||
memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
|
||||
else {
|
||||
char *nodename = utsname()->nodename;
|
||||
int n = strnlen(nodename, 15);
|
||||
memset(vol->source_rfc1001_name, 0x20, 15);
|
||||
for (i = 0; i < n; i++) {
|
||||
/* does not have to be perfect mapping since field is
|
||||
informational, only used for servers that do not support
|
||||
port 445 and it can be overridden at mount time */
|
||||
vol->source_rfc1001_name[i] = toupper(nodename[i]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* does not have to be perfect mapping since field is
|
||||
* informational, only used for servers that do not support
|
||||
* port 445 and it can be overridden at mount time
|
||||
*/
|
||||
memset(vol->source_rfc1001_name, 0x20, 15);
|
||||
for (i = 0; i < strnlen(nodename, 15); i++)
|
||||
vol->source_rfc1001_name[i] = toupper(nodename[i]);
|
||||
|
||||
vol->source_rfc1001_name[15] = 0;
|
||||
/* null target name indicates to use *SMBSERVR default called name
|
||||
if we end up sending RFC1001 session initialize */
|
||||
@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname,
|
||||
/* default to using server inode numbers where available */
|
||||
vol->server_ino = 1;
|
||||
|
||||
vol->actimeo = CIFS_DEF_ACTIMEO;
|
||||
|
||||
if (!options)
|
||||
return 1;
|
||||
|
||||
@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname,
|
||||
printk(KERN_WARNING "CIFS: server net"
|
||||
"biosname longer than 15 truncated.\n");
|
||||
}
|
||||
} else if (strnicmp(data, "actimeo", 7) == 0) {
|
||||
if (value && *value) {
|
||||
vol->actimeo = HZ * simple_strtoul(value,
|
||||
&value, 0);
|
||||
if (vol->actimeo > CIFS_MAX_ACTIMEO) {
|
||||
cERROR(1, "CIFS: attribute cache"
|
||||
"timeout too large");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strnicmp(data, "credentials", 4) == 0) {
|
||||
/* ignore */
|
||||
} else if (strnicmp(data, "version", 3) == 0) {
|
||||
@ -2571,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
|
||||
cFYI(1, "file mode: 0x%x dir mode: 0x%x",
|
||||
cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
|
||||
|
||||
cifs_sb->actimeo = pvolume_info->actimeo;
|
||||
|
||||
if (pvolume_info->noperm)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
|
||||
if (pvolume_info->setuids)
|
||||
@ -2821,13 +2833,13 @@ remote_path_check:
|
||||
/* check if a whole path (including prepath) is not remote */
|
||||
if (!rc && cifs_sb->prepathlen && tcon) {
|
||||
/* build_path_to_root works only when we have a valid tcon */
|
||||
full_path = cifs_build_path_to_root(cifs_sb);
|
||||
full_path = cifs_build_path_to_root(cifs_sb, tcon);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
|
||||
if (rc != -EREMOTE) {
|
||||
if (rc != 0 && rc != -EREMOTE) {
|
||||
kfree(full_path);
|
||||
goto mount_fail_check;
|
||||
}
|
||||
|
@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
|
||||
return total_written;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
|
||||
bool fsuid_only)
|
||||
{
|
||||
@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
|
||||
bool fsuid_only)
|
||||
|
@ -686,7 +686,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
||||
cFYI(1, "cifs_sfu_type failed: %d", tmprc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
#ifdef CONFIG_CIFS_ACL
|
||||
/* fill in 0777 bits from ACL */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
||||
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
|
||||
@ -697,7 +697,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
||||
goto cgii_exit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_CIFS_ACL */
|
||||
|
||||
/* fill in remaining high mode bits e.g. SUID, VTX */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
|
||||
@ -728,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
|
||||
.lookup = cifs_lookup,
|
||||
};
|
||||
|
||||
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
|
||||
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
|
||||
struct cifsTconInfo *tcon)
|
||||
{
|
||||
int pplen = cifs_sb->prepathlen;
|
||||
int dfsplen;
|
||||
char *full_path = NULL;
|
||||
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
|
||||
/* if no prefix path, simply set path to the root of share to "" */
|
||||
if (pplen == 0) {
|
||||
@ -875,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
|
||||
char *full_path;
|
||||
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
|
||||
full_path = cifs_build_path_to_root(cifs_sb);
|
||||
full_path = cifs_build_path_to_root(cifs_sb, tcon);
|
||||
if (full_path == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -1653,6 +1653,7 @@ static bool
|
||||
cifs_inode_needs_reval(struct inode *inode)
|
||||
{
|
||||
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
|
||||
if (cifs_i->clientCanCacheRead)
|
||||
return false;
|
||||
@ -1663,12 +1664,12 @@ cifs_inode_needs_reval(struct inode *inode)
|
||||
if (cifs_i->time == 0)
|
||||
return true;
|
||||
|
||||
/* FIXME: the actimeo should be tunable */
|
||||
if (time_after_eq(jiffies, cifs_i->time + HZ))
|
||||
if (!time_in_range(jiffies, cifs_i->time,
|
||||
cifs_i->time + cifs_sb->actimeo))
|
||||
return true;
|
||||
|
||||
/* hardlinked files w/ noserverino get "special" treatment */
|
||||
if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
|
||||
S_ISREG(inode->i_mode) && inode->i_nlink != 1)
|
||||
return true;
|
||||
|
||||
@ -2121,7 +2122,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
|
||||
if (attrs->ia_valid & ATTR_MODE) {
|
||||
rc = 0;
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
#ifdef CONFIG_CIFS_ACL
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
||||
rc = mode_to_cifs_acl(inode, full_path, mode);
|
||||
if (rc) {
|
||||
@ -2130,7 +2131,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
goto cifs_setattr_exit;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#endif /* CONFIG_CIFS_ACL */
|
||||
if (((mode & S_IWUGO) == 0) &&
|
||||
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
|
||||
|
||||
|
@ -759,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
|
||||
rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
|
||||
ino, fattr.cf_dtype);
|
||||
|
||||
/*
|
||||
* we can not return filldir errors to the caller since they are
|
||||
* "normal" when the stat blocksize is too small - we return remapped
|
||||
* error instead
|
||||
*
|
||||
* FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
|
||||
* case already. Why should we be clobbering other errors from it?
|
||||
*/
|
||||
if (rc) {
|
||||
cFYI(1, "filldir rc = %d", rc);
|
||||
rc = -EOVERFLOW;
|
||||
}
|
||||
dput(tmp_dentry);
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user