/* revalidate:cifs_revalidate, */
.setattr = cifs_setattr,
.symlink = cifs_symlink,
+ .mknod = cifs_mknod,
};
struct inode_operations cifs_file_inode_ops = {
extern struct dentry *cifs_lookup(struct inode *, struct dentry *, struct nameidata *);
extern int cifs_unlink(struct inode *, struct dentry *);
extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
+extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t);
extern int cifs_mkdir(struct inode *, struct dentry *, int);
extern int cifs_rmdir(struct inode *, struct dentry *);
extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
__u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
char *full_path, __u64 mode, __u64 uid,
- __u64 gid, const struct nls_table *nls_codepage);
+ __u64 gid, dev_t dev, const struct nls_table *nls_codepage);
extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
const char *newName,
int
CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
char *fileName, __u64 mode, __u64 uid, __u64 gid,
- const struct nls_table *nls_codepage)
+ dev_t device, const struct nls_table *nls_codepage)
{
TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL;
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
data_offset->Uid = cpu_to_le64(uid);
data_offset->Gid = cpu_to_le64(gid);
+ /* better to leave device as zero when it is */
+ data_offset->DevMajor = cpu_to_le64(MAJOR(device));
+ data_offset->DevMinor = cpu_to_le64(MINOR(device));
data_offset->Permissions = cpu_to_le64(mode);
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
return rc;
}
+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number)
+{
+ int rc = -EPERM;
+ int xid;
+ struct cifs_sb_info *cifs_sb;
+ struct cifsTconInfo *pTcon;
+ char *full_path = NULL;
+ struct inode * newinode = NULL;
+
+ xid = GetXid();
+
+ cifs_sb = CIFS_SB(inode->i_sb);
+ pTcon = cifs_sb->tcon;
+
+ full_path = build_path_from_dentry(direntry);
+
+ if (pTcon->ses->capabilities & CAP_UNIX) {
+ rc = CIFSSMBUnixSetPerms(xid, pTcon,
+ full_path, mode, current->euid, current->egid,
+ device_number, cifs_sb->local_nls);
+ if(!rc) {
+ rc = cifs_get_inode_info_unix(&newinode, full_path,
+ inode->i_sb);
+ direntry->d_op = &cifs_dentry_ops;
+ if(rc == 0)
+ d_instantiate(direntry, newinode);
+ }
+ }
+
+ if (full_path)
+ kfree(full_path);
+ FreeXid(xid);
+
+ return rc;
+}
+
+
struct dentry *
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd)
{
CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
(__u64)-1,
(__u64)-1,
+ 0 /* dev */,
cifs_sb->local_nls);
else {/* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1,
(__u64)-1,
+ 0 /* dev_t */,
cifs_sb->local_nls);
else { /* BB to be implemented via Windows secrty descriptors*/
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
&& (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
- cifs_sb->local_nls);
+ 0 /* dev_t */, cifs_sb->local_nls);
else if (attrs->ia_valid & ATTR_MODE) {
if((mode & S_IWUGO) == 0) /* not writeable */ {
if((cifsInode->cifsAttrs & ATTR_READONLY) == 0)