cifs: obtain file access during backup intent lookup (resend)
Rebased and resending the patch. Path based queries can fail for lack of access, especially during lookup during open. open itself would actually succeed becasue of back up intent bit but queries (either path or file handle based) do not have a means to specifiy backup intent bit. So query the file info during lookup using trans2 / findfirst / file_id_full_dir_info to obtain file info as well as file_id/inode value. Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Acked-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:

committed by
Steve French

parent
f065fd099f
commit
c052e2b423
@@ -607,7 +607,9 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||
FILE_ALL_INFO *data, struct super_block *sb, int xid,
|
||||
const __u16 *fid)
|
||||
{
|
||||
int rc = 0, tmprc;
|
||||
bool validinum = false;
|
||||
__u16 srchflgs;
|
||||
int rc = 0, tmprc = ENOSYS;
|
||||
struct cifs_tcon *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
struct tcon_link *tlink;
|
||||
@@ -615,6 +617,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||
char *buf = NULL;
|
||||
bool adjust_tz = false;
|
||||
struct cifs_fattr fattr;
|
||||
struct cifs_search_info *srchinf = NULL;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
@@ -653,9 +656,38 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||
} else if (rc == -EREMOTE) {
|
||||
cifs_create_dfs_fattr(&fattr, sb);
|
||||
rc = 0;
|
||||
} else {
|
||||
} else if (rc == -EACCES && backup_cred(cifs_sb)) {
|
||||
srchinf = kzalloc(sizeof(struct cifs_search_info),
|
||||
GFP_KERNEL);
|
||||
if (srchinf == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto cgii_exit;
|
||||
}
|
||||
|
||||
srchinf->endOfSearch = false;
|
||||
srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
|
||||
|
||||
srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
|
||||
CIFS_SEARCH_CLOSE_AT_END |
|
||||
CIFS_SEARCH_BACKUP_SEARCH;
|
||||
|
||||
rc = CIFSFindFirst(xid, tcon, full_path,
|
||||
cifs_sb, NULL, srchflgs, srchinf, false);
|
||||
if (!rc) {
|
||||
data =
|
||||
(FILE_ALL_INFO *)srchinf->srch_entries_start;
|
||||
|
||||
cifs_dir_info_to_fattr(&fattr,
|
||||
(FILE_DIRECTORY_INFO *)data, cifs_sb);
|
||||
fattr.cf_uniqueid = le64_to_cpu(
|
||||
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
|
||||
validinum = true;
|
||||
|
||||
cifs_buf_release(srchinf->ntwrk_buf_start);
|
||||
}
|
||||
kfree(srchinf);
|
||||
} else
|
||||
goto cgii_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If an inode wasn't passed in, then get the inode number
|
||||
@@ -666,23 +698,21 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||
*/
|
||||
if (*inode == NULL) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
|
||||
if (server->ops->get_srv_inum)
|
||||
tmprc = server->ops->get_srv_inum(xid, tcon,
|
||||
cifs_sb, full_path, &fattr.cf_uniqueid,
|
||||
data);
|
||||
else
|
||||
tmprc = -ENOSYS;
|
||||
if (tmprc || !fattr.cf_uniqueid) {
|
||||
cFYI(1, "GetSrvInodeNum rc %d", tmprc);
|
||||
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
||||
cifs_autodisable_serverino(cifs_sb);
|
||||
if (validinum == false) {
|
||||
if (server->ops->get_srv_inum)
|
||||
tmprc = server->ops->get_srv_inum(xid,
|
||||
tcon, cifs_sb, full_path,
|
||||
&fattr.cf_uniqueid, data);
|
||||
if (tmprc) {
|
||||
cFYI(1, "GetSrvInodeNum rc %d", tmprc);
|
||||
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
||||
cifs_autodisable_serverino(cifs_sb);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
|
||||
}
|
||||
|
||||
/* query for SFU type info if supported and needed */
|
||||
if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
|
||||
|
Reference in New Issue
Block a user