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 never-used in6_addr option cifs: add addr= mount option alias for ip= [CIFS] Add mention of new mount parm (forceuid) to cifs readme cifs: make overriding of ownership conditional on new mount options cifs: fix IPv6 address length check cifs: clean up set_cifs_acl interfaces cifs: reorganize get_cifs_acl [CIFS] Update readme to indicate change to default mount (serverino) cifs: make serverino the default when mounting cifs: rename cifs_iget to cifs_root_iget cifs: make cnvrtDosUnixTm take a little-endian args and an offset cifs: have cifs_NTtimeToUnix take a little-endian arg cifs: tighten up default file_mode/dir_mode cifs: fix artificial limit on reading symlinks
This commit is contained in:
commit
ddbb868493
|
@ -1,3 +1,12 @@
|
|||
Version 1.59
|
||||
------------
|
||||
Client uses server inode numbers (which are persistent) rather than
|
||||
client generated ones by default (mount option "serverino" turned
|
||||
on by default if server supports it). Add forceuid and forcegid
|
||||
mount options (so that when negotiating unix extensions specifying
|
||||
which uid mounted does not immediately force the server's reported
|
||||
uids to be overridden).
|
||||
|
||||
Version 1.58
|
||||
------------
|
||||
Guard against buffer overruns in various UCS-2 to UTF-8 string conversions
|
||||
|
@ -10,6 +19,8 @@ we converted from). Fix endianness of the vcnum field used during
|
|||
session setup to distinguish multiple mounts to same server from different
|
||||
userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental
|
||||
flag to be set to 2, and mount must enable krb5 to turn on extended security).
|
||||
Performance of file create to Samba improved (posix create on lookup
|
||||
removes 1 of 2 network requests sent on file create)
|
||||
|
||||
Version 1.57
|
||||
------------
|
||||
|
|
|
@ -262,7 +262,8 @@ A partial list of the supported mount options follows:
|
|||
mount.
|
||||
domain Set the SMB/CIFS workgroup name prepended to the
|
||||
username during CIFS session establishment
|
||||
uid Set the default uid for inodes. For mounts to servers
|
||||
forceuid Set the default uid for inodes based on the uid
|
||||
passed in. For mounts to servers
|
||||
which do support the CIFS Unix extensions, such as a
|
||||
properly configured Samba server, the server provides
|
||||
the uid, gid and mode so this parameter should not be
|
||||
|
@ -292,6 +293,12 @@ A partial list of the supported mount options follows:
|
|||
the client. Note that the mount.cifs helper must be
|
||||
at version 1.10 or higher to support specifying the uid
|
||||
(or gid) in non-numeric form.
|
||||
forcegid (similar to above but for the groupid instead of uid)
|
||||
uid Set the default uid for inodes, and indicate to the
|
||||
cifs kernel driver which local user mounted . If the server
|
||||
supports the unix extensions the default uid is
|
||||
not used to fill in the owner fields of inodes (files)
|
||||
unless the "forceuid" parameter is specified.
|
||||
gid Set the default gid for inodes (similar to above).
|
||||
file_mode If CIFS Unix extensions are not supported by the server
|
||||
this overrides the default mode for file inodes.
|
||||
|
@ -388,8 +395,13 @@ A partial list of the supported mount options follows:
|
|||
or the CIFS Unix Extensions equivalent and for those
|
||||
this mount option will have no effect. Exporting cifs mounts
|
||||
under nfsd requires this mount option on the cifs mount.
|
||||
This is now the default if server supports the
|
||||
required network operation.
|
||||
noserverino Client generates inode numbers (rather than using the actual one
|
||||
from the server) by default.
|
||||
from the server). These inode numbers will vary after
|
||||
unmount or reboot which can confuse some applications,
|
||||
but not all server filesystems support unique inode
|
||||
numbers.
|
||||
setuids If the CIFS Unix extensions are negotiated with the server
|
||||
the client will attempt to set the effective uid and gid of
|
||||
the local process on newly created files, directories, and
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <keys/user-type.h>
|
||||
#include <linux/key-type.h>
|
||||
#include <linux/inet.h>
|
||||
#include "cifsglob.h"
|
||||
#include "cifs_spnego.h"
|
||||
#include "cifs_debug.h"
|
||||
|
@ -73,9 +74,6 @@ struct key_type cifs_spnego_key_type = {
|
|||
* strlen(";sec=ntlmsspi") */
|
||||
#define MAX_MECH_STR_LEN 13
|
||||
|
||||
/* max possible addr len eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/128 */
|
||||
#define MAX_IPV6_ADDR_LEN 43
|
||||
|
||||
/* strlen of "host=" */
|
||||
#define HOST_KEY_LEN 5
|
||||
|
||||
|
@ -102,7 +100,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
|
|||
host=hostname sec=mechanism uid=0xFF user=username */
|
||||
desc_len = MAX_VER_STR_LEN +
|
||||
HOST_KEY_LEN + strlen(hostname) +
|
||||
IP_KEY_LEN + MAX_IPV6_ADDR_LEN +
|
||||
IP_KEY_LEN + INET6_ADDRSTRLEN +
|
||||
MAX_MECH_STR_LEN +
|
||||
UID_KEY_LEN + (sizeof(uid_t) * 2) +
|
||||
USER_KEY_LEN + strlen(sesInfo->userName) + 1;
|
||||
|
|
|
@ -552,130 +552,138 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Retrieve an ACL from the server */
|
||||
static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
|
||||
const char *path, const __u16 *pfid)
|
||||
static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
|
||||
__u16 fid, u32 *pacllen)
|
||||
{
|
||||
struct cifsFileInfo *open_file = NULL;
|
||||
bool unlock_file = false;
|
||||
int xid;
|
||||
int rc = -EIO;
|
||||
__u16 fid;
|
||||
struct super_block *sb;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_ntsd *pntsd = NULL;
|
||||
|
||||
cFYI(1, ("get mode from ACL for %s", path));
|
||||
|
||||
if (inode == NULL)
|
||||
return NULL;
|
||||
int xid, rc;
|
||||
|
||||
xid = GetXid();
|
||||
if (pfid == NULL)
|
||||
open_file = find_readable_file(CIFS_I(inode));
|
||||
else
|
||||
fid = *pfid;
|
||||
rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
|
||||
FreeXid(xid);
|
||||
|
||||
sb = inode->i_sb;
|
||||
if (sb == NULL) {
|
||||
FreeXid(xid);
|
||||
return NULL;
|
||||
}
|
||||
cifs_sb = CIFS_SB(sb);
|
||||
|
||||
if (open_file) {
|
||||
unlock_file = true;
|
||||
fid = open_file->netfid;
|
||||
} else if (pfid == NULL) {
|
||||
int oplock = 0;
|
||||
/* open file */
|
||||
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
|
||||
READ_CONTROL, 0, &fid, &oplock, NULL,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
if (rc != 0) {
|
||||
cERROR(1, ("Unable to open file to get ACL"));
|
||||
FreeXid(xid);
|
||||
return NULL;
|
||||
}
|
||||
cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
|
||||
return pntsd;
|
||||
}
|
||||
|
||||
static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
|
||||
const char *path, u32 *pacllen)
|
||||
{
|
||||
struct cifs_ntsd *pntsd = NULL;
|
||||
int oplock = 0;
|
||||
int xid, rc;
|
||||
__u16 fid;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0,
|
||||
&fid, &oplock, NULL, cifs_sb->local_nls,
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unable to open file to get ACL"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
|
||||
cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
|
||||
if (unlock_file == true) /* find_readable_file increments ref count */
|
||||
atomic_dec(&open_file->wrtPending);
|
||||
else if (pfid == NULL) /* if opened above we have to close the handle */
|
||||
CIFSSMBClose(xid, cifs_sb->tcon, fid);
|
||||
/* else handle was passed in by caller */
|
||||
|
||||
CIFSSMBClose(xid, cifs_sb->tcon, fid);
|
||||
out:
|
||||
FreeXid(xid);
|
||||
return pntsd;
|
||||
}
|
||||
|
||||
/* Retrieve an ACL from the server */
|
||||
static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
|
||||
struct inode *inode, const char *path,
|
||||
u32 *pacllen)
|
||||
{
|
||||
struct cifs_ntsd *pntsd = NULL;
|
||||
struct cifsFileInfo *open_file = NULL;
|
||||
|
||||
if (inode)
|
||||
open_file = find_readable_file(CIFS_I(inode));
|
||||
if (!open_file)
|
||||
return get_cifs_acl_by_path(cifs_sb, path, pacllen);
|
||||
|
||||
pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
|
||||
atomic_dec(&open_file->wrtPending);
|
||||
return pntsd;
|
||||
}
|
||||
|
||||
static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
|
||||
struct cifs_ntsd *pnntsd, u32 acllen)
|
||||
{
|
||||
int xid, rc;
|
||||
|
||||
xid = GetXid();
|
||||
rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
|
||||
FreeXid(xid);
|
||||
|
||||
cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
|
||||
struct cifs_ntsd *pnntsd, u32 acllen)
|
||||
{
|
||||
int oplock = 0;
|
||||
int xid, rc;
|
||||
__u16 fid;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0,
|
||||
&fid, &oplock, NULL, cifs_sb->local_nls,
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unable to open file to set ACL"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
|
||||
cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
|
||||
|
||||
CIFSSMBClose(xid, cifs_sb->tcon, fid);
|
||||
out:
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set an ACL on the server */
|
||||
static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
||||
struct inode *inode, const char *path)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsFileInfo *open_file;
|
||||
bool unlock_file = false;
|
||||
int xid;
|
||||
int rc = -EIO;
|
||||
__u16 fid;
|
||||
struct super_block *sb;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
int rc;
|
||||
|
||||
cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
|
||||
|
||||
if (!inode)
|
||||
return rc;
|
||||
|
||||
sb = inode->i_sb;
|
||||
if (sb == NULL)
|
||||
return rc;
|
||||
|
||||
cifs_sb = CIFS_SB(sb);
|
||||
xid = GetXid();
|
||||
|
||||
open_file = find_readable_file(CIFS_I(inode));
|
||||
if (open_file) {
|
||||
unlock_file = true;
|
||||
fid = open_file->netfid;
|
||||
} else {
|
||||
int oplock = 0;
|
||||
/* open file */
|
||||
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
|
||||
WRITE_DAC, 0, &fid, &oplock, NULL,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
if (rc != 0) {
|
||||
cERROR(1, ("Unable to open file to set ACL"));
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
|
||||
cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
|
||||
if (unlock_file)
|
||||
atomic_dec(&open_file->wrtPending);
|
||||
else
|
||||
CIFSSMBClose(xid, cifs_sb->tcon, fid);
|
||||
|
||||
FreeXid(xid);
|
||||
if (!open_file)
|
||||
return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
|
||||
|
||||
rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
|
||||
atomic_dec(&open_file->wrtPending);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
|
||||
void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid)
|
||||
void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,
|
||||
const char *path, const __u16 *pfid)
|
||||
{
|
||||
struct cifs_ntsd *pntsd = NULL;
|
||||
u32 acllen = 0;
|
||||
int rc = 0;
|
||||
|
||||
cFYI(DBG2, ("converting ACL to mode for %s", path));
|
||||
pntsd = get_cifs_acl(&acllen, inode, path, pfid);
|
||||
|
||||
if (pfid)
|
||||
pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
|
||||
else
|
||||
pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
|
||||
|
||||
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
|
||||
if (pntsd)
|
||||
|
@ -698,7 +706,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
|
|||
cFYI(DBG2, ("set ACL from mode for %s", path));
|
||||
|
||||
/* Get the security descriptor */
|
||||
pntsd = get_cifs_acl(&secdesclen, inode, path, NULL);
|
||||
pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
|
||||
|
||||
/* Add three ACEs for owner, group, everyone getting rid of
|
||||
other ACEs as chmod disables ACEs and set the security descriptor */
|
||||
|
|
|
@ -146,7 +146,7 @@ cifs_read_super(struct super_block *sb, void *data,
|
|||
#endif
|
||||
sb->s_blocksize = CIFS_MAX_MSGSIZE;
|
||||
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
|
||||
inode = cifs_iget(sb, ROOT_I);
|
||||
inode = cifs_root_iget(sb, ROOT_I);
|
||||
|
||||
if (IS_ERR(inode)) {
|
||||
rc = PTR_ERR(inode);
|
||||
|
|
|
@ -36,7 +36,7 @@ extern void cifs_read_inode(struct inode *);
|
|||
|
||||
/* Functions related to inodes */
|
||||
extern const struct inode_operations cifs_dir_inode_ops;
|
||||
extern struct inode *cifs_iget(struct super_block *, unsigned long);
|
||||
extern struct inode *cifs_root_iget(struct super_block *, unsigned long);
|
||||
extern int cifs_create(struct inode *, struct dentry *, int,
|
||||
struct nameidata *);
|
||||
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
|
||||
|
@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
|||
extern const struct export_operations cifs_export_ops;
|
||||
#endif /* EXPERIMENTAL */
|
||||
|
||||
#define CIFS_VERSION "1.58"
|
||||
#define CIFS_VERSION "1.59"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
|
|
@ -90,10 +90,10 @@ extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
|
|||
struct cifsTconInfo *);
|
||||
extern void DeleteOplockQEntry(struct oplock_q_entry *);
|
||||
extern void DeleteTconOplockQEntries(struct cifsTconInfo *);
|
||||
extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601);
|
||||
extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
|
||||
extern u64 cifs_UnixTimeToNT(struct timespec);
|
||||
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
|
||||
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
|
||||
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
|
||||
int offset);
|
||||
|
||||
extern int cifs_posix_open(char *full_path, struct inode **pinode,
|
||||
struct super_block *sb, int mode, int oflags,
|
||||
|
@ -108,8 +108,8 @@ extern int cifs_get_inode_info(struct inode **pinode,
|
|||
extern int cifs_get_inode_info_unix(struct inode **pinode,
|
||||
const unsigned char *search_path,
|
||||
struct super_block *sb, int xid);
|
||||
extern void acl_to_uid_mode(struct inode *inode, const char *path,
|
||||
const __u16 *pfid);
|
||||
extern void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,
|
||||
const char *path, const __u16 *pfid);
|
||||
extern int mode_to_acl(struct inode *inode, const char *path, __u64);
|
||||
|
||||
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
|
||||
|
|
|
@ -524,8 +524,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
int val, seconds, remain, result;
|
||||
struct timespec ts, utc;
|
||||
utc = CURRENT_TIME;
|
||||
ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
|
||||
le16_to_cpu(rsp->SrvTime.Time));
|
||||
ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
|
||||
rsp->SrvTime.Time, 0);
|
||||
cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
|
||||
(int)ts.tv_sec, (int)utc.tv_sec,
|
||||
(int)(utc.tv_sec - ts.tv_sec)));
|
||||
|
@ -2427,8 +2427,7 @@ querySymLinkRetry:
|
|||
params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
|
||||
pSMB->TotalDataCount = 0;
|
||||
pSMB->MaxParameterCount = cpu_to_le16(2);
|
||||
/* BB find exact max data count below from sess structure BB */
|
||||
pSMB->MaxDataCount = cpu_to_le16(4000);
|
||||
pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
|
||||
pSMB->MaxSetupCount = 0;
|
||||
pSMB->Reserved = 0;
|
||||
pSMB->Flags = 0;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/namei.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/inet.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "cifspdu.h"
|
||||
#include "cifsglob.h"
|
||||
|
@ -61,7 +62,6 @@ struct smb_vol {
|
|||
char *domainname;
|
||||
char *UNC;
|
||||
char *UNCip;
|
||||
char *in6_addr; /* ipv6 address as human readable form of in6_addr */
|
||||
char *iocharset; /* local code page for mapping to and from Unicode */
|
||||
char source_rfc1001_name[16]; /* netbios name of client */
|
||||
char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
|
||||
|
@ -827,14 +827,16 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
vol->target_rfc1001_name[0] = 0;
|
||||
vol->linux_uid = current_uid(); /* use current_euid() instead? */
|
||||
vol->linux_gid = current_gid();
|
||||
vol->dir_mode = S_IRWXUGO;
|
||||
/* 2767 perms indicate mandatory locking support */
|
||||
vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
|
||||
|
||||
/* default to only allowing write access to owner of the mount */
|
||||
vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
|
||||
|
||||
/* 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;
|
||||
/* default to using server inode numbers where available */
|
||||
vol->server_ino = 1;
|
||||
|
||||
if (!options)
|
||||
return 1;
|
||||
|
@ -955,10 +957,12 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
}
|
||||
strcpy(vol->password, value);
|
||||
}
|
||||
} else if (strnicmp(data, "ip", 2) == 0) {
|
||||
} else if (!strnicmp(data, "ip", 2) ||
|
||||
!strnicmp(data, "addr", 4)) {
|
||||
if (!value || !*value) {
|
||||
vol->UNCip = NULL;
|
||||
} else if (strnlen(value, 35) < 35) {
|
||||
} else if (strnlen(value, INET6_ADDRSTRLEN) <
|
||||
INET6_ADDRSTRLEN) {
|
||||
vol->UNCip = value;
|
||||
} else {
|
||||
printk(KERN_WARNING "CIFS: ip address "
|
||||
|
@ -1092,17 +1096,17 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
return 1;
|
||||
}
|
||||
} else if (strnicmp(data, "uid", 3) == 0) {
|
||||
if (value && *value) {
|
||||
if (value && *value)
|
||||
vol->linux_uid =
|
||||
simple_strtoul(value, &value, 0);
|
||||
} else if (strnicmp(data, "forceuid", 8) == 0) {
|
||||
vol->override_uid = 1;
|
||||
}
|
||||
} else if (strnicmp(data, "gid", 3) == 0) {
|
||||
if (value && *value) {
|
||||
if (value && *value)
|
||||
vol->linux_gid =
|
||||
simple_strtoul(value, &value, 0);
|
||||
} else if (strnicmp(data, "forcegid", 8) == 0) {
|
||||
vol->override_gid = 1;
|
||||
}
|
||||
} else if (strnicmp(data, "file_mode", 4) == 0) {
|
||||
if (value && *value) {
|
||||
vol->file_mode =
|
||||
|
@ -1315,16 +1319,6 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
vol->direct_io = 1;
|
||||
} else if (strnicmp(data, "forcedirectio", 13) == 0) {
|
||||
vol->direct_io = 1;
|
||||
} else if (strnicmp(data, "in6_addr", 8) == 0) {
|
||||
if (!value || !*value) {
|
||||
vol->in6_addr = NULL;
|
||||
} else if (strnlen(value, 49) == 48) {
|
||||
vol->in6_addr = value;
|
||||
} else {
|
||||
printk(KERN_WARNING "CIFS: ip v6 address not "
|
||||
"48 characters long\n");
|
||||
return 1;
|
||||
}
|
||||
} else if (strnicmp(data, "noac", 4) == 0) {
|
||||
printk(KERN_WARNING "CIFS: Mount option noac not "
|
||||
"supported. Instead set "
|
||||
|
|
|
@ -241,7 +241,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
|
|||
/* BB need same check in cifs_create too? */
|
||||
/* if not oplocked, invalidate inode pages if mtime or file
|
||||
size changed */
|
||||
temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
|
||||
temp = cifs_NTtimeToUnix(buf->LastWriteTime);
|
||||
if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
|
||||
(file->f_path.dentry->d_inode->i_size ==
|
||||
(loff_t)le64_to_cpu(buf->EndOfFile))) {
|
||||
|
|
|
@ -85,10 +85,10 @@ static void cifs_unix_info_to_inode(struct inode *inode,
|
|||
__u64 num_of_bytes = le64_to_cpu(info->NumOfBytes);
|
||||
__u64 end_of_file = le64_to_cpu(info->EndOfFile);
|
||||
|
||||
inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime));
|
||||
inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime);
|
||||
inode->i_mtime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime));
|
||||
inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange));
|
||||
cifs_NTtimeToUnix(info->LastModificationTime);
|
||||
inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
|
||||
inode->i_mode = le64_to_cpu(info->Permissions);
|
||||
|
||||
/*
|
||||
|
@ -554,14 +554,11 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
|
||||
/* Linux can not store file creation time so ignore it */
|
||||
if (pfindData->LastAccessTime)
|
||||
inode->i_atime = cifs_NTtimeToUnix
|
||||
(le64_to_cpu(pfindData->LastAccessTime));
|
||||
inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime);
|
||||
else /* do not need to use current_fs_time - time not stored */
|
||||
inode->i_atime = CURRENT_TIME;
|
||||
inode->i_mtime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
|
||||
inode->i_ctime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
|
||||
inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime);
|
||||
inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime);
|
||||
cFYI(DBG2, ("Attributes came in as 0x%x", attr));
|
||||
if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
|
||||
inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
|
||||
|
@ -629,7 +626,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
/* 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, full_path, pfid);
|
||||
acl_to_uid_mode(cifs_sb, inode, full_path, pfid);
|
||||
}
|
||||
#endif
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
|
@ -699,7 +696,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
|
|||
}
|
||||
|
||||
/* gets root inode */
|
||||
struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
||||
struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
|
|
|
@ -853,12 +853,12 @@ smbCalcSize_LE(struct smb_hdr *ptr)
|
|||
|
||||
#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
|
||||
|
||||
/*
|
||||
* Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
|
||||
* into Unix UTC (based 1970-01-01, in seconds).
|
||||
*/
|
||||
/*
|
||||
* Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
|
||||
* into Unix UTC (based 1970-01-01, in seconds).
|
||||
*/
|
||||
struct timespec
|
||||
cifs_NTtimeToUnix(u64 ntutc)
|
||||
cifs_NTtimeToUnix(__le64 ntutc)
|
||||
{
|
||||
struct timespec ts;
|
||||
/* BB what about the timezone? BB */
|
||||
|
@ -866,7 +866,7 @@ cifs_NTtimeToUnix(u64 ntutc)
|
|||
/* Subtract the NTFS time offset, then convert to 1s intervals. */
|
||||
u64 t;
|
||||
|
||||
t = ntutc - NTFS_TIME_OFFSET;
|
||||
t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
|
||||
ts.tv_nsec = do_div(t, 10000000) * 100;
|
||||
ts.tv_sec = t;
|
||||
return ts;
|
||||
|
@ -883,16 +883,12 @@ cifs_UnixTimeToNT(struct timespec t)
|
|||
static int total_days_of_prev_months[] =
|
||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||
|
||||
|
||||
__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
|
||||
{
|
||||
return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
|
||||
}
|
||||
|
||||
struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
|
||||
struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
||||
{
|
||||
struct timespec ts;
|
||||
int sec, min, days, month, year;
|
||||
u16 date = le16_to_cpu(le_date);
|
||||
u16 time = le16_to_cpu(le_time);
|
||||
SMB_TIME *st = (SMB_TIME *)&time;
|
||||
SMB_DATE *sd = (SMB_DATE *)&date;
|
||||
|
||||
|
@ -933,7 +929,7 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
|
|||
days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
|
||||
sec += 24 * 60 * 60 * days;
|
||||
|
||||
ts.tv_sec = sec;
|
||||
ts.tv_sec = sec + offset;
|
||||
|
||||
/* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
|
||||
|
||||
|
|
|
@ -115,17 +115,6 @@ construct_dentry(struct qstr *qstring, struct file *file,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
|
||||
{
|
||||
if ((tcon) && (tcon->ses) && (tcon->ses->server)) {
|
||||
inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
|
||||
inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
|
||||
inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
||||
char *buf, unsigned int *pobject_type, int isNewInode)
|
||||
{
|
||||
|
@ -150,26 +139,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
|||
allocation_size = le64_to_cpu(pfindData->AllocationSize);
|
||||
end_of_file = le64_to_cpu(pfindData->EndOfFile);
|
||||
tmp_inode->i_atime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
|
||||
cifs_NTtimeToUnix(pfindData->LastAccessTime);
|
||||
tmp_inode->i_mtime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
|
||||
cifs_NTtimeToUnix(pfindData->LastWriteTime);
|
||||
tmp_inode->i_ctime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
|
||||
cifs_NTtimeToUnix(pfindData->ChangeTime);
|
||||
} else { /* legacy, OS2 and DOS style */
|
||||
/* struct timespec ts;*/
|
||||
int offset = cifs_sb->tcon->ses->server->timeAdj;
|
||||
FIND_FILE_STANDARD_INFO *pfindData =
|
||||
(FIND_FILE_STANDARD_INFO *)buf;
|
||||
|
||||
tmp_inode->i_mtime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastWriteDate),
|
||||
le16_to_cpu(pfindData->LastWriteTime));
|
||||
tmp_inode->i_atime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastAccessDate),
|
||||
le16_to_cpu(pfindData->LastAccessTime));
|
||||
tmp_inode->i_ctime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastWriteDate),
|
||||
le16_to_cpu(pfindData->LastWriteTime));
|
||||
AdjustForTZ(cifs_sb->tcon, tmp_inode);
|
||||
tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate,
|
||||
pfindData->LastWriteTime,
|
||||
offset);
|
||||
tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate,
|
||||
pfindData->LastAccessTime,
|
||||
offset);
|
||||
tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate,
|
||||
pfindData->LastWriteTime,
|
||||
offset);
|
||||
attr = le16_to_cpu(pfindData->Attributes);
|
||||
allocation_size = le32_to_cpu(pfindData->AllocationSize);
|
||||
end_of_file = le32_to_cpu(pfindData->DataSize);
|
||||
|
@ -331,11 +319,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
|
|||
local_size = tmp_inode->i_size;
|
||||
|
||||
tmp_inode->i_atime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
|
||||
cifs_NTtimeToUnix(pfindData->LastAccessTime);
|
||||
tmp_inode->i_mtime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
|
||||
cifs_NTtimeToUnix(pfindData->LastModificationTime);
|
||||
tmp_inode->i_ctime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
|
||||
cifs_NTtimeToUnix(pfindData->LastStatusChange);
|
||||
|
||||
tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
|
||||
/* since we set the inode type below we need to mask off type
|
||||
|
|
Loading…
Reference in New Issue