linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Pavel Shilovsky
	<piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [PATCH v2 17/53] CIFS: Simplify SMB2 query info
Date: Fri, 28 Oct 2011 23:54:28 +0400	[thread overview]
Message-ID: <1319831704-3572-18-git-send-email-piastry@etersoft.ru> (raw)
In-Reply-To: <1319831704-3572-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>

From: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 fs/cifs/cifsproto.h |   13 +++-
 fs/cifs/dir.c       |    6 +-
 fs/cifs/file.c      |    5 +-
 fs/cifs/inode.c     |  165 +++++++++++++++++----------------------------------
 fs/cifs/smb2dir.c   |   71 ++++++++++++++++++++++
 fs/cifs/smb2glob.h  |    1 +
 fs/cifs/smb2inode.c |  165 +++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/smb2proto.h |   13 ++--
 8 files changed, 311 insertions(+), 128 deletions(-)
 create mode 100644 fs/cifs/smb2dir.c
 create mode 100644 fs/cifs/smb2inode.c

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 5a2d6ef..607d3e4 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -141,14 +141,19 @@ extern struct inode *cifs_iget(struct super_block *sb,
 			       struct cifs_fattr *fattr);
 
 extern int cifs_get_file_info(struct file *filp);
-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(struct inode **pinode, const char *full_path,
+			       void *data, struct super_block *sb, int xid,
+			       const __u16 *fid);
 extern int cifs_get_file_info_unix(struct file *filp);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
 			const unsigned char *search_path,
 			struct super_block *sb, int xid);
+extern void cifs_all_info_to_fattr(struct cifs_fattr *fattr,
+				   FILE_ALL_INFO *info,
+				   struct cifs_sb_info *cifs_sb,
+				   bool adjust_tz);
+extern void cifs_create_dfs_fattr(struct cifs_fattr *fattr,
+				  struct super_block *sb);
 extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
 			      struct cifs_fattr *fattr, struct inode *inode,
 			      const char *path, const __u16 *pfid);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d7eeb9d..3696f5b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -304,8 +304,8 @@ cifs_create_get_file_info:
 		rc = cifs_get_inode_info_unix(&newinode, full_path,
 					      inode->i_sb, xid);
 	else {
-		rc = cifs_get_inode_info(&newinode, full_path, buf,
-					 inode->i_sb, xid, &fileHandle);
+		rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
+					 xid, &fileHandle);
 		if (newinode) {
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
 				newinode->i_mode = mode;
@@ -594,7 +594,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 						parent_dir_inode->i_sb, xid);
 	} else
 		rc = cifs_get_inode_info(&newInode, full_path, NULL,
-				parent_dir_inode->i_sb, xid, NULL);
+					 parent_dir_inode->i_sb, xid, NULL);
 
 	if ((rc == 0) && (newInode != NULL)) {
 		d_add(direntry, newInode);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ea096ce..1b9bae6 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -568,9 +568,8 @@ reopen_success:
 			rc = cifs_get_inode_info_unix(&inode,
 				full_path, inode->i_sb, xid);
 		else
-			rc = cifs_get_inode_info(&inode,
-				full_path, NULL, inode->i_sb,
-				xid, NULL);
+			rc = cifs_get_inode_info(&inode, full_path, NULL,
+						 inode->i_sb, xid, NULL);
 	} /* else we are writing out data to server already
 	     and could deadlock if we tried to flush data, and
 	     since we do not know if we have data that would
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 4d03038..cb5da45 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -32,6 +32,7 @@
 #include "cifs_unicode.h"
 #include "fscache.h"
 #ifdef CONFIG_CIFS_SMB2
+#include "smb2glob.h"
 #include "smb2proto.h"
 #endif
 
@@ -271,7 +272,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
  * junction to the new submount (ie to setup the fake directory
  * which represents a DFS referral).
  */
-static void
+void
 cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 {
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -506,7 +507,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
 }
 
 /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
-static void
+void
 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		       struct cifs_sb_info *cifs_sb, bool adjust_tz)
 {
@@ -598,73 +599,15 @@ cgfi_exit:
 	return rc;
 }
 
-#ifdef CONFIG_CIFS_SMB2
-static void
-move_smb2_info_to_cifs(FILE_ALL_INFO *dst, FILE_ALL_INFO_SMB2 *src)
-{
-	memcpy(dst, src,
-	       (unsigned int)(&src->CurrentByteOffset) - (unsigned int)src);
-	dst->CurrentByteOffset = src->CurrentByteOffset;
-	dst->Mode = src->Mode;
-	dst->AlignmentRequirement = src->AlignmentRequirement;
-	dst->IndexNumber1 = 0; /* we don't use it */
-}
-
 static int
-smb2_qinfo_helper(int xid, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
-		  const unsigned char *full_path, FILE_ALL_INFO *pfindData)
-{
-	const unsigned char *start_full_path = full_path;
-	__u64 persistent_fid, volatile_fid;
-	FILE_ALL_INFO_SMB2 *data = NULL;
-	__le16 *path = NULL;
-	int usc_len, rc;
-
-	data = kzalloc(sizeof(FILE_ALL_INFO_SMB2) + MAX_NAME*2, GFP_KERNEL);
-	if (data == NULL) {
-		rc = -ENOMEM;
-		goto out;
-	}
-
-	if (strlen(full_path) && full_path[0] == '\\')
-		start_full_path += 1;
-
-	path = smb2_strndup_to_ucs(start_full_path,
-				   PATH_MAX, &usc_len,
-				   cifs_sb->local_nls);
-	if (path == NULL) {
-		rc = -ENOMEM;
-		goto out;
-	}
-
-	rc = SMB2_open(xid, tcon, path, &persistent_fid, &volatile_fid,
-		       FILE_READ_ATTRIBUTES_LE, FILE_OPEN_LE, 0, 0);
-	if (!rc) {
-		rc = SMB2_query_info(xid, tcon, persistent_fid,
-				     volatile_fid, data);
-		SMB2_close(xid, tcon, persistent_fid,
-			   volatile_fid);
-	}
-
-	if (rc)
-		goto out;
-
-	move_smb2_info_to_cifs(pfindData, data);
-out:
-	kfree(data);
-	kfree(path);
-	return rc;
-}
-#endif
-
-int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path,
-			FILE_ALL_INFO *pfindData, struct super_block *sb,
-			int xid, const __u16 *pfid)
+cifs_query_inode_info(struct inode **pinode, const char *full_path,
+			FILE_ALL_INFO *data, struct super_block *sb, int xid,
+			const __u16 *fid)
 {
 	int rc = 0, tmprc;
-	struct cifs_tcon *pTcon;
-	struct tcon_link *tlink;
+	struct cifs_tcon *tcon;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	struct tcon_link *tlink;
 	char *buf = NULL;
 	bool adjustTZ = false;
 	struct cifs_fattr fattr;
@@ -672,66 +615,54 @@ int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path,
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
 		return PTR_ERR(tlink);
-	pTcon = tlink_tcon(tlink);
+	tcon = tlink_tcon(tlink);
 
 	cFYI(1, "Getting info on %s", full_path);
 
-	if ((pfindData == NULL) && (*pinode != NULL)) {
+	if ((data == NULL) && (*pinode != NULL)) {
 		if (CIFS_I(*pinode)->clientCanCacheRead) {
 			cFYI(1, "No need to revalidate cached inode sizes");
-			goto cgii_exit;
+			goto cqii_exit;
 		}
 	}
 
 	/* if file info not passed in then get it from server */
-	if (pfindData == NULL) {
+	if (data == NULL) {
 		buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
 		if (buf == NULL) {
 			rc = -ENOMEM;
-			goto cgii_exit;
+			goto cqii_exit;
 		}
-		pfindData = (FILE_ALL_INFO *)buf;
-
-		if (pTcon->ses->server->is_smb2 == false) {
-			/*
-			 * Could do find first instead but this returns more
-			 * info.
-			 */
-			rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
-					      0 /* not legacy */,
-					      cifs_sb->local_nls,
-					      cifs_sb->mnt_cifs_flags &
-					      CIFS_MOUNT_MAP_SPECIAL_CHR);
-			/*
-			 * BB optimize code so we do not make the above call
-			 * when server claims no NT SMB support and the above
-			 * call failed at least once - set flag in tcon or
-			 * mount.
-			 */
-			if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
-				rc = SMBQueryInformation(xid, pTcon, full_path,
-						pfindData, cifs_sb->local_nls,
-						cifs_sb->mnt_cifs_flags &
-						CIFS_MOUNT_MAP_SPECIAL_CHR);
-				adjustTZ = true;
-			}
-#ifdef CONFIG_CIFS_SMB2
-		} else
-			rc = smb2_qinfo_helper(xid, cifs_sb, pTcon, full_path,
-					       pfindData);
-#else
+		data = (FILE_ALL_INFO *)buf;
+
+		/* Could do find first instead but this returns more info */
+		rc = CIFSSMBQPathInfo(xid, tcon, full_path, data,
+				      0 /* not legacy */,
+				      cifs_sb->local_nls,
+				      cifs_sb->mnt_cifs_flags &
+				      CIFS_MOUNT_MAP_SPECIAL_CHR);
+		/*
+		 * BB optimize code so we do not make the above call when server
+		 * claims no NT SMB support and the above call failed at least
+		 * once - set flag in tcon or mount.
+		 */
+		if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
+			rc = SMBQueryInformation(xid, tcon, full_path,
+					data, cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags &
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
+			adjustTZ = true;
 		}
-#endif
 	}
 
 	if (!rc) {
-		cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
+		cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) data,
 				       cifs_sb, adjustTZ);
 	} else if (rc == -EREMOTE) {
 		cifs_create_dfs_fattr(&fattr, sb);
 		rc = 0;
 	} else {
-		goto cgii_exit;
+		goto cqii_exit;
 	}
 
 	/*
@@ -752,11 +683,10 @@ int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path,
 	 * guaranteed unique?
 	 */
 	if (*pinode == NULL) {
-		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
-		    pTcon->ses->server->is_smb2 == false) {
+		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
 			int rc1 = 0;
 
-			rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
+			rc1 = CIFSGetSrvInodeNumber(xid, tcon,
 					full_path, &fattr.cf_uniqueid,
 					cifs_sb->local_nls,
 					cifs_sb->mnt_cifs_flags &
@@ -785,11 +715,11 @@ int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path,
 	/* fill in 0777 bits from ACL */
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
 		rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
-						pfid);
+				       fid);
 		if (rc) {
 			cFYI(1, "%s: Getting ACL failed with error: %d",
 				__func__, rc);
-			goto cgii_exit;
+			goto cqii_exit;
 		}
 	}
 #endif /* CONFIG_CIFS_ACL */
@@ -813,12 +743,25 @@ int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path,
 		cifs_fattr_to_inode(*pinode, &fattr);
 	}
 
-cgii_exit:
+cqii_exit:
 	kfree(buf);
 	cifs_put_tlink(tlink);
 	return rc;
 }
 
+int
+cifs_get_inode_info(struct inode **pinode, const char *full_path, void *data,
+		    struct super_block *sb, int xid, const __u16 *fid)
+{
+#ifdef CONFIG_CIFS_SMB2
+	struct cifs_tcon *tcon = cifs_sb_master_tcon(CIFS_SB(sb));
+
+	if (tcon->ses->server->is_smb2)
+		return smb2_query_inode_info(pinode, full_path, data, sb, xid);
+#endif
+	return cifs_query_inode_info(pinode, full_path, data, sb, xid, fid);
+}
+
 static const struct inode_operations cifs_ipc_inode_ops = {
 	.lookup = cifs_lookup,
 };
@@ -1833,8 +1776,8 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
 		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 	else
-		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
-					 xid, NULL);
+		rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid,
+					 NULL);
 
 out:
 	kfree(full_path);
diff --git a/fs/cifs/smb2dir.c b/fs/cifs/smb2dir.c
new file mode 100644
index 0000000..f297e2c
--- /dev/null
+++ b/fs/cifs/smb2dir.c
@@ -0,0 +1,71 @@
+/*
+ *   fs/cifs/smb2dir.c
+ *
+ *   Copyright (C) 2011
+ *   Author(s): Pavel Shilovsky (piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org),
+ *              Steve French (sfrench-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <asm/div64.h>
+#include "cifsfs.h"
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+#include "cifs_fs_sb.h"
+#include "cifs_unicode.h"
+#include "fscache.h"
+#include "smb2glob.h"
+#include "smb2proto.h"
+
+/* Note: caller must free return buffer */
+__le16 *
+cifs_convert_path_to_ucs(const char *from, struct nls_table *local_nls)
+{
+	int ucs_len;
+	const char *start_of_path;
+	__le16 *ucs_full_path;
+
+	/* Windows doesn't allow paths beginning with \ */
+	if (from[0] == '\\')
+		start_of_path = from + 1;
+	else
+		start_of_path = from;
+	ucs_full_path = smb2_strndup_to_ucs(start_of_path, PATH_MAX,
+					    &ucs_len, local_nls);
+	return ucs_full_path;
+}
+
+__le16 *
+build_ucspath_from_dentry(struct dentry *direntry)
+{
+	char *full_path;
+	__le16 *ucs_path;
+
+	full_path = build_path_from_dentry(direntry);
+	if (full_path == NULL)
+		return NULL;
+
+	ucs_path = cifs_convert_path_to_ucs(full_path,
+					    CIFS_SB(direntry->d_sb)->local_nls);
+	kfree(full_path);
+	return ucs_path;
+}
+
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
index 0e9fba7..1fe5813 100644
--- a/fs/cifs/smb2glob.h
+++ b/fs/cifs/smb2glob.h
@@ -182,6 +182,7 @@ struct page_req {
 #define SMB2_OP_QUERY_DIR 4
 #define SMB2_OP_MKDIR 5
 #define SMB2_OP_RENAME 6
+#define SMB2_OP_DELETE 7
 
 /* Used when constructing chained read requests. */
 #define CHAINED_REQUEST 1
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
new file mode 100644
index 0000000..1d5e139
--- /dev/null
+++ b/fs/cifs/smb2inode.c
@@ -0,0 +1,165 @@
+/*
+ *   fs/cifs/smb2inode.c
+ *
+ *   Copyright (C) 2011
+ *   Author(s): Pavel Shilovsky (piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org),
+ *              Steve French (sfrench-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <asm/div64.h>
+#include "cifsfs.h"
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+#include "cifs_fs_sb.h"
+#include "cifs_unicode.h"
+#include "fscache.h"
+#include "smb2glob.h"
+#include "smb2proto.h"
+
+static int
+smb2_open_op_close(int xid, struct cifs_tcon *tcon, __le16 *path,
+		   __u32 desired_access, __u32 create_disposition,
+		   __u32 file_attributes, __u32 create_options,
+		   void *data, int command)
+{
+	int rc, tmprc = 0;
+	u64 persist_fid, volatile_fid;
+
+	rc = SMB2_open(xid, tcon, srch_path, &persist_fid, &volatile_fid,
+		       desired_access, create_disposition, file_attributes,
+		       create_options);
+	if (rc)
+		return rc;
+
+	switch (command) {
+	case SMB2_OP_DELETE:
+		break;
+	case SMB2_OP_QUERY_INFO:
+		tmprc = SMB2_query_info(xid, tcon, persist_fid,
+					volatile_fid,
+					(FILE_ALL_INFO_SMB2 *)data);
+		break;
+	case SMB2_OP_MKDIR:
+		/* Directories are created through parameters in the
+		 * SMB2_open() call. */
+		break;
+	default:
+		cERROR(1, "Invalid command");
+		break;
+	}
+
+	rc = SMB2_close(xid, tcon, persist_fid, volatile_fid);
+	if (tmprc)
+		rc = tmprc;
+
+	return rc;
+}
+
+static void
+move_smb2_info_to_cifs(FILE_ALL_INFO *dst, FILE_ALL_INFO_SMB2 *src)
+{
+	memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src);
+	dst->CurrentByteOffset = src->CurrentByteOffset;
+	dst->Mode = src->Mode;
+	dst->AlignmentRequirement = src->AlignmentRequirement;
+	dst->IndexNumber1 = 0; /* we don't use it */
+}
+
+static int
+smb2_qinfo_helper(int xid, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
+		  const char *full_path, FILE_ALL_INFO *data)
+{
+	int rc;
+	__le16 *smb2_path;
+	FILE_ALL_INFO_SMB2 *smb2_data;
+
+	smb2_data = kzalloc(sizeof(FILE_ALL_INFO_SMB2) + MAX_NAME*2,
+			    GFP_KERNEL);
+	if (smb2_data == NULL)
+		return -ENOMEM;
+
+	smb2_path = cifs_convert_path_to_ucs(full_path, cifs_sb->local_nls);
+	if (smb2_path == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	rc = smb2_open_op_close(xid, tcon, smb2_path, FILE_READ_ATTRIBUTES,
+				FILE_OPEN, 0, 0, smb2_data,
+				SMB2_OP_QUERY_INFO);
+	if (rc)
+		goto out;
+
+	move_smb2_info_to_cifs(data, smb2_data);
+out:
+	kfree(smb2_path);
+	kfree(smb2_data);
+	return rc;
+}
+
+int smb2_get_inode_info(struct inode **pinode, const char *full_path,
+			FILE_ALL_INFO *data, struct super_block *sb,
+			int xid, struct cifs_tcon *tcon)
+{
+	int rc = 0;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	char *buf = NULL;
+	struct cifs_fattr fattr;
+
+	/* if file info not passed in then get it from server */
+	if (data == NULL) {
+		buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+		if (buf == NULL) {
+			rc = -ENOMEM;
+			goto sgii_exit;
+		}
+		data = (FILE_ALL_INFO *)buf;
+		rc = smb2_qinfo_helper(xid, cifs_sb, tcon, full_path, data);
+	}
+
+	if (!rc) {
+		cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) data,
+				       cifs_sb, false);
+	} else if (rc == -EREMOTE) {
+		cifs_create_dfs_fattr(&fattr, sb);
+		rc = 0;
+	} else {
+		goto sgii_exit;
+	}
+
+	if (*pinode == NULL)
+		fattr.cf_uniqueid = iunique(sb, ROOT_I);
+	else
+		fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
+
+	if (!*pinode) {
+		*pinode = cifs_iget(sb, &fattr);
+		if (!*pinode)
+			rc = -ENOMEM;
+	} else {
+		cifs_fattr_to_inode(*pinode, &fattr);
+	}
+
+sgii_exit:
+	kfree(buf);
+	return rc;
+}
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index e826279..9744dc0 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -47,6 +47,9 @@ extern int checkSMB2(struct smb2_hdr *smb2, __u64 mid, unsigned int length);
 extern char *smb2_get_data_area_len(int *poff, int *pln, struct smb2_hdr *psmb);
 extern unsigned int smb2_calc_size(struct smb2_hdr *ptr);
 extern int map_smb2_to_linux_error(struct smb2_hdr *smb2, int logErr);
+extern __le16 *cifs_build_ucspath_from_dentry(struct dentry *);
+extern __le16 *cifs_convert_path_to_ucs(const char *from,
+					struct nls_table *local_nls);
 
 extern int smb2_send(struct TCP_Server_Info *, struct smb2_hdr *,
 		     unsigned int /* length */);
@@ -76,13 +79,9 @@ extern int smb2_setup_session(unsigned int xid, struct cifs_ses *pses_info,
 			      struct nls_table *nls_info);
 extern int smb2_umount(struct super_block *, struct cifs_sb_info *);
 
-extern int smb2_get_inode_info(struct inode **pinode, __le16 *search_path,
-			FILE_ALL_INFO *pfile_info, struct super_block *sb,
-			int xid);
-extern struct smb2_file *smb2_new_fileinfo(struct inode *newinode,
-					u64 persistfid, u64 volatile_fid,
-					struct file *file, struct vfsmount *mnt,
-					unsigned int oflags);
+extern int smb2_query_inode_info(struct inode **pinode, const char *full_path,
+				 FILE_ALL_INFO *data, struct super_block *sb,
+				 int xid);
 extern bool smb2_is_size_safe_to_change(struct smb2_inode *smb2_ind,
 					__u64 end_of_file);
 extern struct inode *smb2_iget(struct super_block *sb,
-- 
1.7.1

  parent reply	other threads:[~2011-10-28 19:54 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-28 19:54 [PATCH v2 00/53] SMB2 protocol support for CIFS kernel module Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 02/53] CIFS: Allow SMB2 statistics to be tracked Pavel Shilovsky
2011-10-29  4:48   ` Jeff Layton
2011-10-29  5:12     ` Steve French
     [not found]       ` <CAH2r5mtpckA75LEAynsPLVsPfr7U0wnYAyZ1uKeK2VU9F1CGeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-29  5:32         ` Jeff Layton
     [not found]     ` <20111029004814.41340503-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-10-29 19:44       ` Pavel Shilovsky
     [not found]         ` <CAKywueQwBwR-HZtv6gQv32kt4+2qycS7vq5KDLiE3xw3_9=wPA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-30  2:12           ` Jeff Layton
     [not found]             ` <20111029221251.5fba1444-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-10-30  2:52               ` Steve French
2011-10-28 19:54 ` [PATCH v2 03/53] CIFS: Check for smb2 vs. cifs in find_tcp_session Pavel Shilovsky
     [not found]   ` <1319831704-3572-4-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-10-29  4:40     ` Jeff Layton
     [not found]       ` <20111029004046.2bf8e111-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-10-29 19:55         ` Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 05/53] CIFS: wait_for_free_request needs to wait on credits returned by server (for SMB2) Pavel Shilovsky
     [not found]   ` <1319831704-3572-6-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-10-29 15:35     ` Jeff Layton
2011-10-29 20:00       ` Pavel Shilovsky
     [not found]         ` <CAKywueSGDSw33L4_a7W6D7gM_PH9uy3xTQ6=8zgAimGhz5=UfA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-30  2:41           ` Jeff Layton
2011-10-28 19:54 ` [PATCH v2 07/53] CIFS: Add structure definitions for SMB2 PDUs Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 09/53] CIFS: Allocating SMB2 mids (multiplex identifier structures) Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 15/53] CIFS: Make demultiplex_thread work with SMB2 code Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 16/53] CIFS: Get mount/umount work with SMB2 protocol Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 18/53] CIFS: Add SMB2 inode/dentry ops structures Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 19/53] CIFS: Add SMB2 support for mkdir operation Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 22/53] CIFS: Add SMB2 support for open/close file operations Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 23/53] CIFS: Add SMB2 support for reopen file operation Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 25/53] CIFS: Add SMB2 support for cifs_iovec_read Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 26/53] CIFS: Add address space ops structures for SMB2 Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 28/53] CIFS: Add write related address space operations " Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 30/53] CIFS: Temporarily disable set inode info " Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 31/53] CIFS: Add writepages support " Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 32/53] CIFS: Add readpages " Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 33/53] CIFS: Add echo request " Pavel Shilovsky
     [not found] ` <1319831704-3572-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-10-28 19:54   ` [PATCH v2 01/53] CIFS: Update cifs global structures to handle smb2 sessions Pavel Shilovsky
     [not found]     ` <1319831704-3572-2-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-10-29  4:54       ` Jeff Layton
2011-10-28 19:54   ` [PATCH v2 04/53] CIFS: Do not try to dump cifs mids from " Pavel Shilovsky
     [not found]     ` <1319831704-3572-5-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-10-29  5:05       ` Jeff Layton
2011-10-28 19:54   ` [PATCH v2 06/53] CIFS: Add missing unicode handling routines needed by smb2 Pavel Shilovsky
     [not found]     ` <1319831704-3572-7-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-11-01 10:12       ` Jeff Layton
2011-11-01 13:52       ` Shirish Pargaonkar
2011-12-29 15:01         ` Pavel Shilovsky
2011-12-30 12:42           ` Jeff Layton
2012-01-12 10:47             ` Pavel Shilovsky
2012-01-12 17:22       ` Shirish Pargaonkar
     [not found]         ` <CADT32eJ7FMkQZiy4LjeEG3axvt99N7jFEod7-u2js1MnhVkc7Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-12 18:42           ` Jeff Layton
2012-01-12 19:58             ` Shirish Pargaonkar
     [not found]               ` <CADT32eKc=Xq5G1cE+pye6h1dN6sjry+b7V0ze7CTMJXC8JCtwA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-12 20:48                 ` Jeff Layton
2012-01-12 20:41       ` Shirish Pargaonkar
2011-10-28 19:54   ` [PATCH v2 10/53] CIFS: Add routines to free SMB2 mids Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 11/53] CIFS: Add sync_smb2_mid_result Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 13/53] CIFS: Add SMB2 transport routines Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 14/53] CIFS: Expand cifs mid structure to keep SMB2 related fields Pavel Shilovsky
2011-10-28 19:54   ` Pavel Shilovsky [this message]
2011-10-28 19:54   ` [PATCH v2 20/53] CIFS: Add SMB2 support for rmdir operation Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 21/53] CIFS: Add SMB2 support for unlink operation Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 24/53] CIFS: Add SMB2 support for cifs_iovec_write Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 27/53] CIFS: Add read related address space operations for SMB2 Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 29/53] CIFS: Respect max buf size for SMB2 read and write Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 34/53] [CIFS] Add SMB2 support for cifs_get_file_info Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 35/53] CIFS: Add SMB2 support for create operation Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 36/53] CIFS: Add readdir support for SMB2 Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 37/53] CIFS: Add SMB2 support for rename operation Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 38/53] CIFS: Add SMB2 support for hardlink operation Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 40/53] CIFS: Add NTLMSSP sec type to defaults Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 41/53] CIFS: Disable SMB2.1 protocol negotiating Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 43/53] CIFS: Process STATUS_PENDING responses for SMB2 Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 44/53] CIFS: Request SMB2.1 leases Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 45/53] CIFS: Process oplock/lease break for SMB2/2.1 Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 47/53] CIFS: Enable signing in SMB2 Pavel Shilovsky
2011-10-28 19:54   ` [PATCH v2 48/53] CIFS: Process signing for SMB2_logoff Pavel Shilovsky
2011-10-28 19:55   ` [PATCH v2 49/53] CIFS: Introduce SMB2 Kconfig option Pavel Shilovsky
2011-10-28 19:55   ` [PATCH v2 50/53] CIFS: Introduce smb2 mounts as vers=2 Pavel Shilovsky
2011-10-28 19:55   ` [PATCH v2 53/53] CIFS: Disable lock call for SMB2 since we don't support it Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 39/53] CIFS: Add SMB2 support for flush operation Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 42/53] CIFS: Process oplocks for SMB2 Pavel Shilovsky
2011-10-28 19:54 ` [PATCH v2 46/53] CIFS: Add strictcache i/o " Pavel Shilovsky
2011-10-28 19:55 ` [PATCH v2 51/53] CIFS: Change Makefile to support CONFIG_CIFS_SMB2 Pavel Shilovsky
2011-10-28 19:55 ` [PATCH v2 52/53] CIFS: Add statfs support for SMB2 Pavel Shilovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1319831704-3572-18-git-send-email-piastry@etersoft.ru \
    --to=piastry-7qunaywfiewox3rin2dayq@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).