Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: when ATTR_READONLY is set, only clear write bits on non-directories
  cifs: remove cifsInodeInfo->inUse counter
  cifs: convert cifs_get_inode_info and non-posix readdir to use cifs_iget
  [CIFS] update cifs version number
  cifs: add and use CIFSSMBUnixSetFileInfo for setattr calls
  cifs: make a separate function for filling out FILE_UNIX_BASIC_INFO
  cifs: rename CIFSSMBUnixSetInfo to CIFSSMBUnixSetPathInfo
  cifs: add pid of initiating process to spnego upcall info
  cifs: fix regression with O_EXCL creates and optimize away lookup
  cifs: add new cifs_iget function and convert unix codepath to use it
  • Loading branch information
Linus Torvalds committed Jul 10, 2009
2 parents e864561 + d0c280d commit c2cc49a
Show file tree
Hide file tree
Showing 13 changed files with 686 additions and 896 deletions.
6 changes: 5 additions & 1 deletion fs/cifs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ 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). Add support for scope moutn parm.
uids to be overridden). Add support for scope mount parm. Improve
hard link detection to use same inode for both. Do not set
read-only dos attribute on directories (for chmod) since Windows
explorer special cases this attribute bit for directories for
a different purpose.

Version 1.58
------------
Expand Down
9 changes: 8 additions & 1 deletion fs/cifs/cifs_spnego.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ struct key_type cifs_spnego_key_type = {
/* strlen of ";user=" */
#define USER_KEY_LEN 6

/* strlen of ";pid=0x" */
#define PID_KEY_LEN 7

/* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
Expand All @@ -103,7 +106,8 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
IP_KEY_LEN + INET6_ADDRSTRLEN +
MAX_MECH_STR_LEN +
UID_KEY_LEN + (sizeof(uid_t) * 2) +
USER_KEY_LEN + strlen(sesInfo->userName) + 1;
USER_KEY_LEN + strlen(sesInfo->userName) +
PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;

spnego_key = ERR_PTR(-ENOMEM);
description = kzalloc(desc_len, GFP_KERNEL);
Expand Down Expand Up @@ -141,6 +145,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
dp = description + strlen(description);
sprintf(dp, ";user=%s", sesInfo->userName);

dp = description + strlen(description);
sprintf(dp, ";pid=0x%x", current->pid);

cFYI(1, ("key description = %s", description));
spnego_key = request_key(&cifs_spnego_key_type, description, "");

Expand Down
26 changes: 13 additions & 13 deletions fs/cifs/cifsacl.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)

static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
struct inode *inode)
struct cifs_fattr *fattr)
{
int i;
int num_aces = 0;
Expand All @@ -340,7 +340,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
if (!pdacl) {
/* no DACL in the security descriptor, set
all the permissions for user/group/other */
inode->i_mode |= S_IRWXUGO;
fattr->cf_mode |= S_IRWXUGO;
return;
}

Expand All @@ -357,7 +357,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
/* reset rwx permissions for user/group/other.
Also, if num_aces is 0 i.e. DACL has no ACEs,
user/group/other have no permissions */
inode->i_mode &= ~(S_IRWXUGO);
fattr->cf_mode &= ~(S_IRWXUGO);

acl_base = (char *)pdacl;
acl_size = sizeof(struct cifs_acl);
Expand All @@ -379,17 +379,17 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
if (compare_sids(&(ppace[i]->sid), pownersid))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
&(inode->i_mode),
&fattr->cf_mode,
&user_mask);
if (compare_sids(&(ppace[i]->sid), pgrpsid))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
&(inode->i_mode),
&fattr->cf_mode,
&group_mask);
if (compare_sids(&(ppace[i]->sid), &sid_everyone))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
&(inode->i_mode),
&fattr->cf_mode,
&other_mask);

/* memcpy((void *)(&(cifscred->aces[i])),
Expand Down Expand Up @@ -464,15 +464,15 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)

/* Convert CIFS ACL to POSIX form */
static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
struct inode *inode)
struct cifs_fattr *fattr)
{
int rc;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl = ((char *)pntsd) + acl_len;
__u32 dacloffset;

if ((inode == NULL) || (pntsd == NULL))
if (pntsd == NULL)
return -EIO;

owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
Expand All @@ -497,7 +497,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,

if (dacloffset)
parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
group_sid_ptr, inode);
group_sid_ptr, fattr);
else
cFYI(1, ("no ACL")); /* BB grant all or default perms? */

Expand All @@ -508,7 +508,6 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
sizeof(struct cifs_sid)); */


return 0;
}

Expand Down Expand Up @@ -671,8 +670,9 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
}

/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,
const char *path, const __u16 *pfid)
void
cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
struct inode *inode, const char *path, const __u16 *pfid)
{
struct cifs_ntsd *pntsd = NULL;
u32 acllen = 0;
Expand All @@ -687,7 +687,7 @@ void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,

/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
if (pntsd)
rc = parse_sec_desc(pntsd, acllen, inode);
rc = parse_sec_desc(pntsd, acllen, fattr);
if (rc)
cFYI(1, ("parse sec desc failed rc = %d", rc));

Expand Down
1 change: 0 additions & 1 deletion fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ cifs_alloc_inode(struct super_block *sb)
if (!cifs_inode)
return NULL;
cifs_inode->cifsAttrs = 0x20; /* default */
atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0;
cifs_inode->write_behind_rc = 0;
/* Until the file is open and we have gotten oplock
Expand Down
15 changes: 14 additions & 1 deletion fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@

#define ROOT_I 2

/*
* ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
* so that it will fit.
*/
static inline ino_t
cifs_uniqueid_to_ino_t(u64 fileid)
{
ino_t ino = (ino_t) fileid;
if (sizeof(ino_t) < sizeof(u64))
ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8;
return ino;
}

extern struct file_system_type cifs_fs_type;
extern const struct address_space_operations cifs_addr_ops;
extern const struct address_space_operations cifs_addr_ops_smallbuf;
Expand Down Expand Up @@ -100,5 +113,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.59"
#define CIFS_VERSION "1.60"
#endif /* _CIFSFS_H */
28 changes: 27 additions & 1 deletion fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,13 @@ struct cifsInodeInfo {
struct list_head openFileList;
int write_behind_rc;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
atomic_t inUse; /* num concurrent users (local openers cifs) of file*/
unsigned long time; /* jiffies of last update/check of inode */
bool clientCanCacheRead:1; /* read oplock */
bool clientCanCacheAll:1; /* read and writebehind oplock */
bool oplockPending:1;
bool delete_pending:1; /* DELETE_ON_CLOSE is set */
u64 server_eof; /* current file size on server */
u64 uniqueid; /* server inode number */
struct inode vfs_inode;
};

Expand Down Expand Up @@ -472,6 +472,32 @@ struct dfs_info3_param {
char *node_name;
};

/*
* common struct for holding inode info when searching for or updating an
* inode with new info
*/

#define CIFS_FATTR_DFS_REFERRAL 0x1
#define CIFS_FATTR_DELETE_PENDING 0x2
#define CIFS_FATTR_NEED_REVAL 0x4

struct cifs_fattr {
u32 cf_flags;
u32 cf_cifsattrs;
u64 cf_uniqueid;
u64 cf_eof;
u64 cf_bytes;
uid_t cf_uid;
gid_t cf_gid;
umode_t cf_mode;
dev_t cf_rdev;
unsigned int cf_nlink;
unsigned int cf_dtype;
struct timespec cf_atime;
struct timespec cf_mtime;
struct timespec cf_ctime;
};

static inline void free_dfs_info_param(struct dfs_info3_param *param)
{
if (param) {
Expand Down
14 changes: 1 addition & 13 deletions fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2328,19 +2328,7 @@ struct file_attrib_tag {
typedef struct {
__le32 NextEntryOffset;
__u32 ResumeKey; /* as with FileIndex - no need to convert */
__le64 EndOfFile;
__le64 NumOfBytes;
__le64 LastStatusChange; /*SNIA specs DCE time for the 3 time fields */
__le64 LastAccessTime;
__le64 LastModificationTime;
__le64 Uid;
__le64 Gid;
__le32 Type;
__le64 DevMajor;
__le64 DevMinor;
__le64 UniqueId;
__le64 Permissions;
__le64 Nlinks;
FILE_UNIX_BASIC_INFO basic;
char FileName[1];
} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */

Expand Down
21 changes: 15 additions & 6 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,23 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
extern int cifs_posix_open(char *full_path, struct inode **pinode,
struct super_block *sb, int mode, int oflags,
int *poplock, __u16 *pnetfid, int xid);
extern void posix_fill_in_inode(struct inode *tmp_inode,
FILE_UNIX_BASIC_INFO *pData, int isNewInode);
extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum);
extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
FILE_UNIX_BASIC_INFO *info,
struct cifs_sb_info *cifs_sb);
extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern struct inode *cifs_iget(struct super_block *sb,
struct cifs_fattr *fattr);

extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path,
FILE_ALL_INFO *pfile_info,
struct super_block *sb, int xid, const __u16 *pfid);
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 cifs_sb_info *cifs_sb, struct inode *inode,
const char *path, const __u16 *pfid);
extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
struct cifs_fattr *fattr, 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 *,
Expand Down Expand Up @@ -215,7 +220,11 @@ struct cifs_unix_set_info_args {
dev_t device;
};

extern int CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *pTcon,
extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
const struct cifs_unix_set_info_args *args,
u16 fid, u32 pid_of_opener);

extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon,
char *fileName,
const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage,
Expand Down
Loading

0 comments on commit c2cc49a

Please sign in to comment.