[PATCH] cifs: add support for chattr/lsattr in new CIFS POSIX extensions
Signed-off-by: Steve French (sfrench@us.ibm.com) Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
1da0c78b32
commit
f654bac222
@ -2072,7 +2072,91 @@ setACLerrorExit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* BB fix tabs in this function FIXME BB */
|
||||
int
|
||||
CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
|
||||
const int netfid, __u64 * pExtAttrBits, __u64 *pMask)
|
||||
{
|
||||
int rc = 0;
|
||||
struct smb_t2_qfi_req *pSMB = NULL;
|
||||
struct smb_t2_qfi_rsp *pSMBr = NULL;
|
||||
int bytes_returned;
|
||||
__u16 params, byte_count;
|
||||
|
||||
cFYI(1,("In GetExtAttr"));
|
||||
if(tcon == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
GetExtAttrRetry:
|
||||
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
|
||||
(void **) &pSMBr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
params = 2 /* level */ +2 /* fid */ + 2 /* rsrvd */;
|
||||
pSMB->t2.TotalDataCount = 0;
|
||||
pSMB->t2.MaxParameterCount = cpu_to_le16(2);
|
||||
/* BB find exact max data count below from sess structure BB */
|
||||
pSMB->t2.MaxDataCount = cpu_to_le16(4000);
|
||||
pSMB->t2.MaxSetupCount = 0;
|
||||
pSMB->t2.Reserved = 0;
|
||||
pSMB->t2.Flags = 0;
|
||||
pSMB->t2.Timeout = 0;
|
||||
pSMB->t2.Reserved2 = 0;
|
||||
pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(
|
||||
struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
|
||||
pSMB->t2.DataCount = 0;
|
||||
pSMB->t2.DataOffset = 0;
|
||||
pSMB->t2.SetupCount = 1;
|
||||
pSMB->t2.Reserved3 = 0;
|
||||
pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
|
||||
byte_count = params + 3 /* pad */ ;
|
||||
pSMB->t2.TotalParameterCount = cpu_to_le16(params);
|
||||
pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
|
||||
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
|
||||
pSMB->Pad1 = 0;
|
||||
pSMB->Pad2 = 0;
|
||||
pSMB->Fid = netfid;
|
||||
pSMB->hdr.smb_buf_length += byte_count;
|
||||
pSMB->t2.ByteCount = cpu_to_le16(byte_count);
|
||||
|
||||
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
if (rc) {
|
||||
cFYI(1, ("error %d in GetExtAttr", rc));
|
||||
} else {
|
||||
/* decode response */
|
||||
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
||||
if (rc || (pSMBr->ByteCount < 2))
|
||||
/* BB also check enough total bytes returned */
|
||||
/* If rc should we check for EOPNOSUPP and
|
||||
disable the srvino flag? or in caller? */
|
||||
rc = -EIO; /* bad smb */
|
||||
else {
|
||||
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
||||
__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
|
||||
struct file_chattr_info * pfinfo;
|
||||
/* BB Do we need a cast or hash here ? */
|
||||
if(count != 16) {
|
||||
cFYI(1, ("Illegal size ret in GetExtAttr"));
|
||||
rc = -EIO;
|
||||
goto GetExtAttrOut;
|
||||
}
|
||||
pfinfo = (struct file_chattr_info *)
|
||||
(data_offset + (char *) &pSMBr->hdr.Protocol);
|
||||
*pExtAttrBits = le64_to_cpu(pfinfo->mode);
|
||||
*pMask = le64_to_cpu(pfinfo->mask);
|
||||
}
|
||||
}
|
||||
GetExtAttrOut:
|
||||
cifs_buf_release(pSMB);
|
||||
if (rc == -EAGAIN)
|
||||
goto GetExtAttrRetry;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_POSIX */
|
||||
|
||||
int
|
||||
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
|
Reference in New Issue
Block a user