From: "Q (Igor Mammedov)" <qwerty0987654321@mail.ru>
To: "Christoph Hellwig" <hch@infradead.org>
Cc: linux-fsdevel <linux-fsdevel@vger.kernel.org>,
Steve French <smfrench@gmail.com>,
linux-cifs-client@lists.samba.org
Subject: Re: review 5, was Re: projected date for mount.cifs to support DFS junction points
Date: Sun, 9 Mar 2008 01:21:13 +0300 [thread overview]
Message-ID: <71bff3710803081421l7f248614t44762d00bbf17af@mail.gmail.com> (raw)
In-Reply-To: <20080308184127.GA1461@infradead.org>
[-- Attachment #1.1: Type: text/plain, Size: 2019 bytes --]
Thanks for your comments. Fixed patch is attached.
On Sat, Mar 8, 2008 at 9:41 PM, Christoph Hellwig <hch@infradead.org> wrote:
> On Tue, Mar 04, 2008 at 03:38:50PM +0300, Q (Igor Mammedov) wrote:
> > Hi Steve,
> >
> > Looked through inode.c code again and rewrote/simplified patch5
> > See attachment for it.
>
> Thanks, this looks much better. A few (mostly cosmetic) comments:
>
>
> >From 03c5dcdd566f59240de7843e0a4dd3c3468a0ace Mon Sep 17 00:00:00 2001
> From: Igor Mammedov <niallain@gmail.com>
> Date: Tue, 4 Mar 2008 15:12:27 +0300
> Subject: [PATCH] DFS patch that connects inode with dfs handling ops
> if it is DFS junction point.
>
> +#define PATH_IN_DFS 1
> +#define PATH_NOT_IN_DFS 0
> +static void cifs_set_ops(const int in_dfs, struct inode *inode)
>
>
> I think this would be better done as
>
> static void cifs_set_ops(struct inode *inode, bool is_dfs_referral)
>
>
> Rationale: a) flags should always come last
> b) if there's only two choices a boolean is better
> than flags
>
>
> + full_path = cifs_get_search_path(pTcon, search_path);
> + tmp_path = full_path != search_path?full_path:NULL;
>
> tmp_path is only used to free full_path in case it's different
> from search_path. It think it would be easier and more clear
> to just guard the kfree with an
>
> if (full_path != search_path)
> kfree(full_path);
>
> Or am I missing something?
>
> +
> + if ((rc == -EREMOTE) && (in_dfs == PATH_NOT_IN_DFS)) {
>
> No need for the inner braces here, just
>
> if (rc == -EREMOTE && in_dfs == PATH_NOT_IN_DFS) {
>
> Or with my suggestions from above:
>
> if (rc == -EREMOTE && is_dfs_reffereal) {
>
> + kfree(tmp_path);
> + return rc;
>
> Please only do this cleanup and return in one place and use
> an goto out_free_path to jump there from the inside of the
> function.
>
[-- Attachment #1.2: Type: text/html, Size: 3145 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0005-DFS-patch-that-connects-inode-with-dfs-handling-ops.090308.patch --]
[-- Type: text/x-patch; name=0005-DFS-patch-that-connects-inode-with-dfs-handling-ops.090308.patch, Size: 7948 bytes --]
From e9901b3d09e09382fb73963da5f9475c9bbe6fb3 Mon Sep 17 00:00:00 2001
From: root <root@DMZ_ROUTER.(none)>
Date: Sun, 9 Mar 2008 07:03:38 -0400
Subject: [PATCH] DFS patch that connects inode with dfs handling ops
if it is DFS junction point.
Signed-off-by: Igor Mammedov <niallain@gmail.com>
---
fs/cifs/inode.c | 133 +++++++++++++++++++++++++++++-------------------------
1 files changed, 71 insertions(+), 62 deletions(-)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 24eb4d3..e4bfd70 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -30,7 +30,7 @@
#include "cifs_fs_sb.h"
-static void cifs_set_ops(struct inode *inode)
+static void cifs_set_ops(struct inode *inode, const bool is_dfs_reffereal)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -57,8 +57,12 @@ static void cifs_set_ops(struct inode *inode)
inode->i_data.a_ops = &cifs_addr_ops;
break;
case S_IFDIR:
- inode->i_op = &cifs_dir_inode_ops;
- inode->i_fop = &cifs_dir_ops;
+ if (is_dfs_reffereal) {
+ inode->i_op = &cifs_dfs_referral_inode_operations;
+ } else {
+ inode->i_op = &cifs_dir_inode_ops;
+ inode->i_fop = &cifs_dir_ops;
+ }
break;
case S_IFLNK:
inode->i_op = &cifs_symlink_inode_ops;
@@ -153,6 +157,30 @@ static void cifs_unix_info_to_inode(struct inode *inode,
spin_unlock(&inode->i_lock);
}
+static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon,
+ const char *search_path)
+{
+ int tree_len;
+ int path_len;
+ char *tmp_path;
+
+ if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
+ return search_path;
+
+ /* use full path name for working with DFS */
+ tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1);
+ path_len = strnlen(search_path, MAX_PATHCONF);
+
+ tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL);
+ if (tmp_path == NULL)
+ return search_path;
+
+ strncpy(tmp_path, pTcon->treeName, tree_len);
+ strncpy(tmp_path+tree_len, search_path, path_len);
+ tmp_path[tree_len+path_len] = 0;
+ return tmp_path;
+}
+
int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, struct super_block *sb, int xid)
{
@@ -161,41 +189,28 @@ int cifs_get_inode_info_unix(struct inode **pinode,
struct cifsTconInfo *pTcon;
struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- char *tmp_path;
+ const unsigned char *full_path;
+ bool is_dfs_reffereal = false;
pTcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", search_path));
+
+ full_path = cifs_get_search_path(pTcon, search_path);
+
+try_again_CIFSSMBUnixQPathInfo:
/* could have done a find first instead but this returns more info */
- rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
+ rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* dump_mem("\nUnixQPathInfo return data", &findData,
sizeof(findData)); */
if (rc) {
- if (rc == -EREMOTE) {
- tmp_path =
- kmalloc(strnlen(pTcon->treeName,
- MAX_TREE_SIZE + 1) +
- strnlen(search_path, MAX_PATHCONF) + 1,
- GFP_KERNEL);
- if (tmp_path == NULL)
- return -ENOMEM;
-
- /* have to skip first of the double backslash of
- UNC name */
- strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
- strncat(tmp_path, search_path, MAX_PATHCONF);
- rc = connect_to_dfs_path(xid, pTcon->ses,
- /* treename + */ tmp_path,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- kfree(tmp_path);
-
- /* BB fix up inode etc. */
- } else if (rc) {
- return rc;
+ if (rc == -EREMOTE && !is_dfs_reffereal) {
+ is_dfs_reffereal = true;
+ full_path = search_path;
+ goto try_again_CIFSSMBUnixQPathInfo;
}
+ goto cgiiu_exit;
} else {
struct cifsInodeInfo *cifsInfo;
__u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
@@ -204,8 +219,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
- if (*pinode == NULL)
- return -ENOMEM;
+ if (*pinode == NULL) {
+ rc = -ENOMEM;
+ goto cgiiu_exit;
+ }
/* Is an i_ino of zero legal? */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
@@ -237,8 +254,11 @@ int cifs_get_inode_info_unix(struct inode **pinode,
(unsigned long) inode->i_size,
(unsigned long long)inode->i_blocks));
- cifs_set_ops(inode);
+ cifs_set_ops(inode, is_dfs_reffereal);
}
+cgiiu_exit:
+ if (full_path != search_path)
+ kfree(full_path);
return rc;
}
@@ -353,9 +373,10 @@ int cifs_get_inode_info(struct inode **pinode,
struct cifsTconInfo *pTcon;
struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- char *tmp_path;
+ const unsigned char *full_path;
char *buf = NULL;
int adjustTZ = FALSE;
+ bool is_dfs_reffereal = false;
pTcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", search_path));
@@ -373,8 +394,12 @@ int cifs_get_inode_info(struct inode **pinode,
if (buf == NULL)
return -ENOMEM;
pfindData = (FILE_ALL_INFO *)buf;
+
+ full_path = cifs_get_search_path(pTcon, search_path);
+
+try_again_CIFSSMBQPathInfo:
/* could do find first instead but this returns more info */
- rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
+ rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
0 /* not legacy */,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -382,7 +407,7 @@ int cifs_get_inode_info(struct inode **pinode,
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, search_path,
+ rc = SMBQueryInformation(xid, pTcon, full_path,
pfindData, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -391,31 +416,12 @@ int cifs_get_inode_info(struct inode **pinode,
}
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if (rc) {
- if (rc == -EREMOTE) {
- tmp_path =
- kmalloc(strnlen
- (pTcon->treeName,
- MAX_TREE_SIZE + 1) +
- strnlen(search_path, MAX_PATHCONF) + 1,
- GFP_KERNEL);
- if (tmp_path == NULL) {
- kfree(buf);
- return -ENOMEM;
- }
-
- strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
- strncat(tmp_path, search_path, MAX_PATHCONF);
- rc = connect_to_dfs_path(xid, pTcon->ses,
- /* treename + */ tmp_path,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- kfree(tmp_path);
- /* BB fix up inode etc. */
- } else if (rc) {
- kfree(buf);
- return rc;
+ if (rc == -EREMOTE && !is_dfs_reffereal) {
+ is_dfs_reffereal = true;
+ full_path = search_path;
+ goto try_again_CIFSSMBQPathInfo;
}
+ goto cgii_exit;
} else {
struct cifsInodeInfo *cifsInfo;
__u32 attr = le32_to_cpu(pfindData->Attributes);
@@ -424,8 +430,8 @@ int cifs_get_inode_info(struct inode **pinode,
if (*pinode == NULL) {
*pinode = new_inode(sb);
if (*pinode == NULL) {
- kfree(buf);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto cgii_exit;
}
/* Is an i_ino of zero legal? Can we use that to check
if the server supports returning inode numbers? Are
@@ -573,8 +579,11 @@ int cifs_get_inode_info(struct inode **pinode,
atomic_set(&cifsInfo->inUse, 1);
}
- cifs_set_ops(inode);
+ cifs_set_ops(inode, is_dfs_reffereal);
}
+cgii_exit:
+ if (full_path != search_path)
+ kfree(full_path);
kfree(buf);
return rc;
}
@@ -804,7 +813,7 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
local_size = tmp_inode->i_size;
cifs_unix_info_to_inode(tmp_inode, pData, 1);
- cifs_set_ops(tmp_inode);
+ cifs_set_ops(tmp_inode, false);
if (!S_ISREG(tmp_inode->i_mode))
return;
--
1.5.3.2
[-- Attachment #3: Type: text/plain, Size: 172 bytes --]
_______________________________________________
linux-cifs-client mailing list
linux-cifs-client@lists.samba.org
https://lists.samba.org/mailman/listinfo/linux-cifs-client
next prev parent reply other threads:[~2008-03-08 22:21 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1199988975.7483.3.camel@gn2.draper.com>
2008-01-10 20:28 ` projected date for mount.cifs to support DFS junction points Steve French
2008-01-11 9:07 ` Christoph Hellwig
2008-01-11 16:05 ` Steve French
2008-01-13 19:40 ` review 1, was " Christoph Hellwig
2008-01-13 21:26 ` Steve French
2008-01-13 19:48 ` review 2, " Christoph Hellwig
2008-01-13 21:35 ` Steve French
2008-01-13 19:50 ` review 3, " Christoph Hellwig
2008-01-13 20:19 ` review 4, " Christoph Hellwig
2008-01-14 13:15 ` Q (Igor Mammedov)
2008-01-14 21:53 ` [linux-cifs-client] " Christoph Hellwig
2008-01-13 20:21 ` review 5, " Christoph Hellwig
2008-02-15 16:37 ` Q (Igor Mammedov)
2008-02-15 17:05 ` [linux-cifs-client] " Christoph Hellwig
2008-02-15 21:02 ` Steve French
2008-02-15 22:11 ` [linux-cifs-client] " Christoph Hellwig
2008-02-19 4:51 ` Steve French
2008-02-25 20:25 ` Steve French
2008-03-08 18:43 ` Christoph Hellwig
2008-03-11 3:34 ` Steve French
2008-03-11 12:39 ` Jeff Layton
2008-03-17 3:14 ` [linux-cifs-client] " simo
2008-02-16 8:51 ` Re[2]: " Q
2008-02-16 13:32 ` Christoph Hellwig
2008-03-04 12:38 ` Q (Igor Mammedov)
2008-03-08 18:41 ` [linux-cifs-client] " Christoph Hellwig
2008-03-08 22:21 ` Q (Igor Mammedov) [this message]
2008-03-09 3:49 ` Steve French
2008-03-10 6:14 ` Christoph Hellwig
2008-03-10 16:20 ` Steve French
2008-03-11 9:41 ` Q (Igor Mammedov)
2008-03-11 22:14 ` Steve French
2008-03-12 9:28 ` Q (Igor Mammedov)
2008-03-22 22:48 ` [linux-cifs-client] " Steve French
2008-04-18 16:40 ` Igor Mammedov
2008-02-06 4:07 ` Christoph Hellwig
2008-02-06 13:43 ` Steve French
2008-02-07 18:25 ` Christoph Hellwig
2008-02-07 23:30 ` Steve French
2008-02-08 5:27 ` Steve French
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=71bff3710803081421l7f248614t44762d00bbf17af@mail.gmail.com \
--to=qwerty0987654321@mail.ru \
--cc=hch@infradead.org \
--cc=linux-cifs-client@lists.samba.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=smfrench@gmail.com \
/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).