Commit d1b8ea55 authored by Steve French's avatar Steve French

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
parents 310b411f af337a9c
......@@ -197,6 +197,8 @@ static read_proc_t ntlmv2_enabled_read;
static write_proc_t ntlmv2_enabled_write;
static read_proc_t packet_signing_enabled_read;
static write_proc_t packet_signing_enabled_write;
static read_proc_t quotaEnabled_read;
static write_proc_t quotaEnabled_write;
void
cifs_proc_init(void)
......@@ -233,6 +235,11 @@ cifs_proc_init(void)
if (pde)
pde->write_proc = oplockEnabled_write;
pde = create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs,
quotaEnabled_read, 0);
if (pde)
pde->write_proc = quotaEnabled_write;
pde =
create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
multiuser_mount_read, 0);
......@@ -361,6 +368,47 @@ oplockEnabled_write(struct file *file, const char *buffer,
return count;
}
static int
quotaEnabled_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = sprintf(page, "%d\n", quotaEnabled);
/* could also check if quotas are enabled in kernel
as a whole first */
len -= off;
*start = page + off;
if (len > count)
len = count;
else
*eof = 1;
if (len < 0)
len = 0;
return len;
}
static int
quotaEnabled_write(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char c;
int rc;
rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '0' || c == 'n' || c == 'N')
quotaEnabled = 0;
else if (c == '1' || c == 'y' || c == 'Y')
quotaEnabled = 1;
return count;
}
static int
lookupFlag_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
......
......@@ -42,12 +42,17 @@
#include <linux/mm.h>
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of all SMB PDUs */
#ifdef CIFS_QUOTA
static struct quotactl_ops cifs_quotactl_ops;
#endif
extern struct file_system_type cifs_fs_type;
int cifsFYI = 0;
int cifsERROR = 1;
int traceSMB = 0;
unsigned int oplockEnabled = 1;
unsigned int quotaEnabled = 0;
unsigned int lookupCacheEnabled = 1;
unsigned int multiuser_mount = 0;
unsigned int extended_security = 0;
......@@ -92,7 +97,9 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_op = &cifs_super_ops;
/* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CIFS_QUOTA
sb->s_qcop = &cifs_quotactl_ops;
#endif
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
inode = iget(sb, ROOT_I);
......@@ -247,6 +254,110 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
return 0;
}
#ifdef CIFS_QUOTA
int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
struct fs_disk_quota * pdquota)
{
int xid;
int rc = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *pTcon;
if(cifs_sb)
pTcon = cifs_sb->tcon;
else
return -EIO;
xid = GetXid();
if(pTcon) {
cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
} else {
return -EIO;
}
FreeXid(xid);
return rc;
}
int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
struct fs_disk_quota * pdquota)
{
int xid;
int rc = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *pTcon;
if(cifs_sb)
pTcon = cifs_sb->tcon;
else
return -EIO;
xid = GetXid();
if(pTcon) {
cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
} else {
rc = -EIO;
}
FreeXid(xid);
return rc;
}
int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
{
int xid;
int rc = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *pTcon;
if(cifs_sb)
pTcon = cifs_sb->tcon;
else
return -EIO;
xid = GetXid();
if(pTcon) {
cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
} else {
rc = -EIO;
}
FreeXid(xid);
return rc;
}
int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
{
int xid;
int rc = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *pTcon;
if(cifs_sb) {
pTcon = cifs_sb->tcon;
} else {
return -EIO;
}
xid = GetXid();
if(pTcon) {
cFYI(1,("pqstats %p",qstats));
} else {
rc = -EIO;
}
FreeXid(xid);
return rc;
}
static struct quotactl_ops cifs_quotactl_ops = {
.set_xquota = cifs_xquota_set,
.get_xquota = cifs_xquota_set,
.set_xstate = cifs_xstate_set,
.get_xstate = cifs_xstate_get,
};
#endif
struct super_operations cifs_super_ops = {
.read_inode = cifs_read_inode,
.put_super = cifs_put_super,
......
......@@ -347,6 +347,7 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
have the uid/password or Kerberos credential
or equivalent for current user */
GLOBAL_EXTERN unsigned int oplockEnabled;
GLOBAL_EXTERN unsigned int quotaEnabled;
GLOBAL_EXTERN unsigned int lookupCacheEnabled;
GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
......
......@@ -68,6 +68,8 @@
#define NT_TRANSACT_NOTIFY_CHANGE 0x04
#define NT_TRANSACT_RENAME 0x05
#define NT_TRANSACT_QUERY_SECURITY_DESC 0x06
#define NT_TRANSACT_GET_USER_QUOTA 0x07
#define NT_TRANSACT_SET_USER_QUOTA 0x08
#define MAX_CIFS_HDR_SIZE 256 /* chained NTCreateXReadX will probably be biggest */
......@@ -878,6 +880,21 @@ struct reparse_data {
char LinkNamesBuf[1];
};
struct cifs_quota_data {
__u32 rsrvd1; /* 0 */
__u32 sid_size;
__u64 rsrvd2; /* 0 */
__u64 space_used;
__u64 soft_limit;
__u64 hard_limit;
char sid[1]; /* variable size? */
};
/* quota sub commands */
#define QUOTA_LIST_CONTINUE 0
#define QUOTA_LIST_START 0x100
#define QUOTA_FOR_SID 0x101
typedef union smb_com_transaction2 {
struct {
struct smb_hdr hdr; /* wct = 14+ */
......@@ -941,6 +958,7 @@ typedef union smb_com_transaction2 {
#define SMB_SET_FILE_UNIX_LINK 0x201
#define SMB_SET_FILE_UNIX_HLINK 0x203
#define SMB_SET_FILE_BASIC_INFO2 0x3ec
#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2
#define SMB_SET_FILE_ALLOCATION_INFO2 0x3fb
#define SMB_SET_FILE_END_OF_FILE_INFO2 0x3fc
......@@ -1036,6 +1054,13 @@ typedef struct smb_com_transaction2_spi_rsp {
__u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
} TRANSACTION2_SPI_RSP;
struct set_file_rename {
__u32 overwrite; /* 1 = overwrite dest */
__u32 root_fid; /* zero */
__u32 target_name_len;
char target_name[0]; /* Must be unicode */
};
struct smb_com_transaction2_sfi_req {
struct smb_hdr hdr; /* wct = 15 */
__u16 TotalParameterCount;
......
......@@ -170,6 +170,8 @@ extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int netfid, const struct nls_table *nls_codepage);
extern int CIFSCreateHardLink(const int xid,
struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
......
......@@ -762,6 +762,72 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
return rc;
}
int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int netfid, const struct nls_table * nls_codepage)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
struct set_file_rename * rename_info;
char *data_offset;
int rc = 0;
int bytes_returned = 0;
int len_of_str;
cFYI(1, ("Rename to Dummy Random File Name"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
pSMB->ParameterCount = 6;
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
Fid) - 4;
pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
rename_info = (struct set_file_rename *) data_offset;
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
/* construct random name ".cifs_tmp<inodenum><mid>" */
rename_info->overwrite = cpu_to_le32(1);
rename_info->root_fid = 0;
len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, ".cifs", 12, nls_codepage);
pSMB->DataCount = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
pSMB->ByteCount += pSMB->DataCount;
pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
pSMB->Fid = netfid;
/* should we check the passthrough bit ? */
pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1,("Send error in DummyRename = %d", rc));
}
if (pSMB)
buf_release(pSMB);
return rc;
}
int
CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
......@@ -1979,7 +2045,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cERROR(1, ("Send error in QFSDeviceInfo = %d", rc));
cFYI(1, ("Send error in QFSDeviceInfo = %d", rc));
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))
......@@ -2202,10 +2268,10 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
pSMB->TotalDataCount = pSMB->DataCount;
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
parm_data =
(struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
pSMB->DataOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset); /* now safe to change to le */
parm_data->FileSize = size;
pSMB->Fid = fid;
if(SetAllocation) {
......
......@@ -1114,9 +1114,6 @@ construct_dentry(struct qstr *qstring, struct file *file,
}
tmp_dentry->d_time = jiffies;
(*ptmp_inode)->i_blksize =
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;
cFYI(1, ("i_blksize = %ld", (*ptmp_inode)->i_blksize));
*pnew_dentry = tmp_dentry;
}
......
......@@ -353,8 +353,9 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) {
CIFSSMBDummyRenameOpenFile(xid,pTcon,netfid,
cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid);
/* BB In the future chain close with the NTCreateX to narrow window */
direntry->d_inode->i_nlink--;
}
} else if (rc == -EACCES) {
......@@ -370,8 +371,22 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
}
if(rc==0) {
rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls);
if (!rc)
if (!rc) {
direntry->d_inode->i_nlink--;
} else if (rc == -ETXTBSY) {
int oplock = FALSE;
__u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) {
CIFSSMBDummyRenameOpenFile(xid,pTcon,netfid,cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid);
direntry->d_inode->i_nlink--;
}
/* BB if rc = -ETXTBUSY goto the rename logic BB */
}
}
}
cifsInode = CIFS_I(direntry->d_inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment