* [CIFS] Support for Minshall+French symlinks
@ 2010-08-03 15:05 Stefan Metzmacher
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
0 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Hi Steve,
The following patchset adds support Minshall+French symlinks for Linux.
See http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks
I've added a new mount option 'mfsymlinks', which is off by default.
If the option is pass to a mount, Minshall+French symlinks will be used
to support symlinks for the local client.
This is compatible with the Darwin implementation.
Can you review this patches? It would be wonderful if they would endup
in Linux 2.6.36.
metze
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 1/8] cifs: add "mfsymlinks" mount option
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-03 15:05 ` Stefan Metzmacher
[not found] ` <1280847960-16371-2-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
` (7 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
This is the start for an implementation of "Minshall+French Symlinks"
(see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks).
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/README | 5 +++++
fs/cifs/cifs_fs_sb.h | 1 +
fs/cifs/cifsfs.c | 2 ++
fs/cifs/connect.c | 11 +++++++++++
4 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/README b/fs/cifs/README
index a727b7c..228c239 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -517,6 +517,11 @@ A partial list of the supported mount options follows:
SFU does). In the future the bottom 9 bits of the
mode also will be emulated using queries of the security
descriptor (ACL).
+ mfsymlinks Enable support for Minshall+French symlinks
+ (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks)
+ This option is ignored when specified together with the
+ 'sfu' option. Minshall+French symlinks are used event if
+ the server supports the CIFS Unix Extensions.
sign Must use packet signing (helps avoid unwanted data modification
by intermediate systems in the route). Note that signing
does not work with lanman or plaintext authentication.
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 9e77145..7fde529 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -36,6 +36,7 @@
#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */
+#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8a2cf12..ec48c96 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -421,6 +421,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",dynperm");
if (m->mnt_sb->s_flags & MS_POSIXACL)
seq_printf(s, ",acl");
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ seq_printf(s, ",mfsymlinks");
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2a43a0a..b3b8752 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -100,6 +100,7 @@ struct smb_vol {
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool fsc:1; /* enable fscache */
+ bool mfsymlinks:1; /* use Minshall+French Symlinks */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
@@ -1343,6 +1344,8 @@ cifs_parse_mount_options(char *options, const char *devname,
"/proc/fs/cifs/LookupCacheEnabled to 0\n");
} else if (strnicmp(data, "fsc", 3) == 0) {
vol->fsc = true;
+ } else if (strnicmp(data, "mfsymlinks", 22) == 0) {
+ vol->mfsymlinks = true;
} else
printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
data);
@@ -2481,6 +2484,14 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cFYI(1, "mounting share using direct i/o");
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
}
+ if (pvolume_info->mfsymlinks) {
+ if (pvolume_info->sfu_emul) {
+ cERROR(1, "mount option mfsymlinks ignored if sfu "
+ "mount option is used");
+ } else {
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
+ }
+ }
if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
cERROR(1, "mount option dynperm ignored if cifsacl "
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
[not found] ` <1280847960-16371-3-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
` (6 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 34 ++++++++++++++++++++++++++++++----
1 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 473ca80..2358a5f 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -29,6 +29,24 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+static int
+CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
+ const char *fromName, const char *toName,
+ const struct nls_table *nls_codepage)
+{
+ int rc = -EOPNOTSUPP;
+ return rc;
+}
+
+static int
+CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName, char **symlinkinfo,
+ const struct nls_table *nls_codepage)
+{
+ int rc = -EOPNOTSUPP;
+ return rc;
+}
+
int
cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
@@ -130,7 +148,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
* but there doesn't seem to be any harm in allowing the client to
* read them.
*/
- if (!(tcon->ses->capabilities & CAP_UNIX)) {
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ && !(tcon->ses->capabilities & CAP_UNIX)) {
rc = -EACCES;
goto out;
}
@@ -141,8 +160,12 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
- rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls);
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
+ cifs_sb->local_nls);
+ else
+ rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
+ cifs_sb->local_nls);
kfree(full_path);
out:
if (rc != 0) {
@@ -182,7 +205,10 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
cFYI(1, "symname is %s", symname);
/* BB what if DFS and this volume is on different share? BB */
- if (pTcon->unix_ext)
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
+ cifs_sb->local_nls);
+ else if (pTcon->unix_ext)
rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls);
/* else
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
` (5 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/cifsproto.h | 3 +++
fs/cifs/inode.c | 7 +++++++
fs/cifs/link.c | 8 ++++++++
3 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 2eaebbd..e94e095 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
+extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
+ const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid);
#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a15b3a9..c4121de 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
+ /* query for SFU type info if supported and needed */
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
+ tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
+ if (tmprc)
+ cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
+ }
+
if (!*pinode) {
*pinode = cifs_iget(sb, &fattr);
if (!*pinode)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 2358a5f..985373c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -48,6 +48,14 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
}
int
+CIFSCheckMFSymlink(struct cifs_fattr *fattr,
+ const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid)
+{
+ return 0;
+}
+
+int
cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
{
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 4/8] cifs: implement CIFSParseMFSymlink()
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (2 preceding siblings ...)
2010-08-03 15:05 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
` (4 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 985373c..33307b1 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -28,6 +28,67 @@
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+#include "md5.h"
+
+#define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
+#define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
+#define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
+#define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
+#define CIFS_MF_SYMLINK_FILE_SIZE (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
+
+#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
+#define CIFS_MF_SYMLINK_MD5_FORMAT \
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
+#define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
+ md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
+ md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
+ md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
+ md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
+
+static int
+CIFSParseMFSymlink(const u8 *buf,
+ unsigned int buf_len,
+ unsigned int *_link_len,
+ char **_link_str)
+{
+ int rc;
+ unsigned int link_len;
+ const char *md5_str1;
+ const char *link_str;
+ struct MD5Context md5_ctx;
+ u8 md5_hash[16];
+ char md5_str2[34];
+
+ if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
+ return -EINVAL;
+
+ md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
+ link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
+
+ rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
+ if (rc != 1)
+ return -EINVAL;
+
+ cifs_MD5_init(&md5_ctx);
+ cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
+ cifs_MD5_final(md5_hash, &md5_ctx);
+
+ snprintf(md5_str2, sizeof(md5_str2),
+ CIFS_MF_SYMLINK_MD5_FORMAT,
+ CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
+
+ if (strncmp(md5_str1, md5_str2, 17) != 0)
+ return -EINVAL;
+
+ if (_link_str) {
+ *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
+ if (!*_link_str)
+ return -ENOMEM;
+ }
+
+ *_link_len = link_len;
+ return 0;
+}
static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 5/8] cifs: implement CIFSCheckMFSymlink()
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (3 preceding siblings ...)
2010-08-03 15:05 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
` (3 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 33307b1..f7636f9 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -113,6 +113,66 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
{
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ struct cifsTconInfo *pTcon = cifs_sb->tcon;
+ u8 buf[CIFS_MF_SYMLINK_FILE_SIZE];
+ char *pbuf = buf;
+ unsigned int bytes_read = 0;
+ int buf_type = CIFS_NO_BUFFER;
+ unsigned int link_len = 0;
+ FILE_ALL_INFO file_info;
+
+ if (!(fattr->cf_mode & S_IFREG)) {
+ /* it's not a symlink */
+ return 0;
+ }
+
+ if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE) {
+ /* it's not a symlink */
+ return 0;
+ }
+
+ rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
+ CREATE_NOT_DIR, &netfid, &oplock, &file_info,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+ CIFSSMBClose(xid, pTcon, netfid);
+ /* it's not a symlink */
+ return 0;
+ }
+
+ /* Read header */
+ rc = CIFSSMBRead(xid, pTcon, netfid,
+ CIFS_MF_SYMLINK_FILE_SIZE /* length */,
+ 0 /* offset */,
+ &bytes_read, &pbuf, &buf_type);
+ CIFSSMBClose(xid, pTcon, netfid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
+ if (rc == EINVAL) {
+ /* it's not a symlink */
+ return 0;
+ }
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* it is a symlink */
+ fattr->cf_eof = link_len;
+ fattr->cf_mode &= ~S_IFMT;
+ fattr->cf_mode |= S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
return 0;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 6/8] cifs: implement CIFSQueryMFSymLink()
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (4 preceding siblings ...)
2010-08-03 15:05 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
[not found] ` <1280847960-16371-7-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
` (2 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index f7636f9..77f5a40 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -102,10 +102,46 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
static int
CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, char **symlinkinfo,
- const struct nls_table *nls_codepage)
+ const struct nls_table *nls_codepage, int remap)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ u8 buf[CIFS_MF_SYMLINK_FILE_SIZE];
+ char *pbuf = buf;
+ unsigned int bytes_read = 0;
+ int buf_type = CIFS_NO_BUFFER;
+ unsigned int link_len = 0;
+ FILE_ALL_INFO file_info;
+
+ rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
+ CREATE_NOT_DIR, &netfid, &oplock, &file_info,
+ nls_codepage, remap);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+ CIFSSMBClose(xid, tcon, netfid);
+ /* it's not a symlink */
+ return -EINVAL;
+ }
+
+ rc = CIFSSMBRead(xid, tcon, netfid,
+ CIFS_MF_SYMLINK_FILE_SIZE /* length */,
+ 0 /* offset */,
+ &bytes_read, &pbuf, &buf_type);
+ CIFSSMBClose(xid, tcon, netfid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
}
int
@@ -291,7 +327,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls);
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
else
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
cifs_sb->local_nls);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 7/8] cifs: implement CIFSFormatMFSymlink()
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (5 preceding siblings ...)
2010-08-03 15:05 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
@ 2010-08-03 15:05 ` Stefan Metzmacher
2010-08-03 15:06 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
2010-08-03 18:00 ` [CIFS] Support for Minshall+French symlinks Steve French
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:05 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 77f5a40..b281d26 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -91,6 +91,48 @@ CIFSParseMFSymlink(const u8 *buf,
}
static int
+CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
+{
+ unsigned int link_len;
+ unsigned int ofs;
+ struct MD5Context md5_ctx;
+ u8 md5_hash[16];
+
+ if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
+ return -EINVAL;
+
+ link_len = strlen(link_str);
+
+ if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
+ return -ENAMETOOLONG;
+
+ cifs_MD5_init(&md5_ctx);
+ cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
+ cifs_MD5_final(md5_hash, &md5_ctx);
+
+ snprintf(buf, buf_len,
+ CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
+ link_len,
+ CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
+
+ ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
+ memcpy(buf + ofs, link_str, link_len);
+
+ ofs += link_len;
+ if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
+ buf[ofs] = '\n';
+ ofs++;
+ }
+
+ while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
+ buf[ofs] = ' ';
+ ofs++;
+ }
+
+ return 0;
+}
+
+static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 8/8] cifs: implement CIFSCreateMFSymLink()
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (6 preceding siblings ...)
2010-08-03 15:05 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
@ 2010-08-03 15:06 ` Stefan Metzmacher
[not found] ` <1280847960-16371-9-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 18:00 ` [CIFS] Support for Minshall+French symlinks Steve French
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-03 15:06 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 39 +++++++++++++++++++++++++++++++++++----
1 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index b281d26..93d2dfd 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -135,10 +135,39 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
- const struct nls_table *nls_codepage)
+ const struct nls_table *nls_codepage, int remap)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ u8 buf[CIFS_MF_SYMLINK_FILE_SIZE];
+ unsigned int bytes_written = 0;
+
+ rc = CIFSFormatMFSymlink(buf, sizeof(buf), toName);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
+ CREATE_NOT_DIR, &netfid, &oplock, NULL,
+ nls_codepage, remap);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = CIFSSMBWrite(xid, tcon, netfid,
+ sizeof(buf) /* length */,
+ 0 /* offset */,
+ &bytes_written, buf, NULL, 0);
+ CIFSSMBClose(xid, tcon, netfid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (bytes_written != sizeof(buf))
+ return -EIO;
+
+ return 0;
}
static int
@@ -416,7 +445,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
/* BB what if DFS and this volume is on different share? BB */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
- cifs_sb->local_nls);
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
else if (pTcon->unix_ext)
rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 8/8] cifs: implement CIFSCreateMFSymLink()
[not found] ` <1280847960-16371-9-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-03 15:29 ` Jeff Layton
0 siblings, 0 replies; 31+ messages in thread
From: Jeff Layton @ 2010-08-03 15:29 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On Tue, 3 Aug 2010 17:06:00 +0200
Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/link.c | 39 +++++++++++++++++++++++++++++++++++----
> 1 files changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index b281d26..93d2dfd 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -135,10 +135,39 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
> static int
> CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
> const char *fromName, const char *toName,
> - const struct nls_table *nls_codepage)
> + const struct nls_table *nls_codepage, int remap)
> {
> - int rc = -EOPNOTSUPP;
> - return rc;
> + int rc;
> + int oplock = 0;
> + __u16 netfid = 0;
> + u8 buf[CIFS_MF_SYMLINK_FILE_SIZE];
^^^^^^^^^^^^^^
Oof. You really don't want to do this -- allocating this much on the
stack is a good way to get memory corruption. I'd kmalloc this
buffer instead.
> + unsigned int bytes_written = 0;
> +
> + rc = CIFSFormatMFSymlink(buf, sizeof(buf), toName);
> + if (rc != 0) {
> + return rc;
> + }
> +
> + rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
> + CREATE_NOT_DIR, &netfid, &oplock, NULL,
> + nls_codepage, remap);
> + if (rc != 0) {
> + return rc;
> + }
> +
> + rc = CIFSSMBWrite(xid, tcon, netfid,
> + sizeof(buf) /* length */,
> + 0 /* offset */,
> + &bytes_written, buf, NULL, 0);
> + CIFSSMBClose(xid, tcon, netfid);
> + if (rc != 0) {
> + return rc;
> + }
> +
> + if (bytes_written != sizeof(buf))
> + return -EIO;
> +
> + return 0;
> }
>
> static int
> @@ -416,7 +445,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
> /* BB what if DFS and this volume is on different share? BB */
> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
> rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
> - cifs_sb->local_nls);
> + cifs_sb->local_nls,
> + cifs_sb->mnt_cifs_flags &
> + CIFS_MOUNT_MAP_SPECIAL_CHR);
> else if (pTcon->unix_ext)
> rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
> cifs_sb->local_nls);
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 6/8] cifs: implement CIFSQueryMFSymLink()
[not found] ` <1280847960-16371-7-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-03 16:31 ` Jeff Layton
0 siblings, 0 replies; 31+ messages in thread
From: Jeff Layton @ 2010-08-03 16:31 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On Tue, 3 Aug 2010 17:05:58 +0200
Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/link.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
> 1 files changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index f7636f9..77f5a40 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -102,10 +102,46 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
> static int
> CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
> const unsigned char *searchName, char **symlinkinfo,
> - const struct nls_table *nls_codepage)
> + const struct nls_table *nls_codepage, int remap)
> {
> - int rc = -EOPNOTSUPP;
> - return rc;
> + int rc;
> + int oplock = 0;
> + __u16 netfid = 0;
> + u8 buf[CIFS_MF_SYMLINK_FILE_SIZE];
^^^^
as noted before, you don't want to allocate these big buffers on the stack
> + char *pbuf = buf;
> + unsigned int bytes_read = 0;
> + int buf_type = CIFS_NO_BUFFER;
> + unsigned int link_len = 0;
> + FILE_ALL_INFO file_info;
> +
> + rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
> + CREATE_NOT_DIR, &netfid, &oplock, &file_info,
> + nls_codepage, remap);
> + if (rc != 0) {
> + return rc;
> + }
> +
In general, kernel coding style leaves out braces when the
inside of an if block is a single statement. IOW, this should
read:
if (rc != 0)
return rc;
> + if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
> + CIFSSMBClose(xid, tcon, netfid);
> + /* it's not a symlink */
> + return -EINVAL;
> + }
> +
> + rc = CIFSSMBRead(xid, tcon, netfid,
> + CIFS_MF_SYMLINK_FILE_SIZE /* length */,
> + 0 /* offset */,
> + &bytes_read, &pbuf, &buf_type);
> + CIFSSMBClose(xid, tcon, netfid);
> + if (rc != 0) {
> + return rc;
> + }
> +
> + rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
> + if (rc != 0) {
> + return rc;
> + }
> +
> + return 0;
> }
>
> int
> @@ -291,7 +327,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
>
> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
> rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
> - cifs_sb->local_nls);
> + cifs_sb->local_nls,
> + cifs_sb->mnt_cifs_flags &
> + CIFS_MOUNT_MAP_SPECIAL_CHR);
> else
> rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
> cifs_sb->local_nls);
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [CIFS] Support for Minshall+French symlinks
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (7 preceding siblings ...)
2010-08-03 15:06 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
@ 2010-08-03 18:00 ` Steve French
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
8 siblings, 1 reply; 31+ messages in thread
From: Steve French @ 2010-08-03 18:00 UTC (permalink / raw)
To: Stefan Metzmacher; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Interesting.
Generally seems like a good idea.
Jeff made two valid review comments already (on the kmalloc vs. stack,
and the kernel coding style) but note that scripts/checkpatch.pl will
catch additional minor coding style things:
stevef@stevef-laptop:~/smb2$ scripts/checkpatch.pl ~/sm1.patch
WARNING: braces {} are not necessary for single statement blocks
#62: FILE: fs/cifs/link.c:120:
+ if (rc != 0) {
+ return rc;
+ }
Could you clean up the things scripts/checkpatch.pl (and sparse
issues, ie "make modules C=1" -- if any)
On Tue, Aug 3, 2010 at 10:05 AM, Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Hi Steve,
>
> The following patchset adds support Minshall+French symlinks for Linux.
> See http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks
>
> I've added a new mount option 'mfsymlinks', which is off by default.
>
> If the option is pass to a mount, Minshall+French symlinks will be used
> to support symlinks for the local client.
>
> This is compatible with the Darwin implementation.
>
> Can you review this patches? It would be wonderful if they would endup
> in Linux 2.6.36.
>
> metze
>
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [CIFS] Support for Minshall+French symlinks
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
` (7 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Hi Steve,
here's the updated patchset.
metze
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 1/8] cifs: add "mfsymlinks" mount option
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-08-04 14:11 ` Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
` (6 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
This is the start for an implementation of "Minshall+French Symlinks"
(see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks).
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/README | 5 +++++
fs/cifs/cifs_fs_sb.h | 1 +
fs/cifs/cifsfs.c | 2 ++
fs/cifs/connect.c | 11 +++++++++++
4 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/README b/fs/cifs/README
index a727b7c..228c239 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -517,6 +517,11 @@ A partial list of the supported mount options follows:
SFU does). In the future the bottom 9 bits of the
mode also will be emulated using queries of the security
descriptor (ACL).
+ mfsymlinks Enable support for Minshall+French symlinks
+ (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks)
+ This option is ignored when specified together with the
+ 'sfu' option. Minshall+French symlinks are used event if
+ the server supports the CIFS Unix Extensions.
sign Must use packet signing (helps avoid unwanted data modification
by intermediate systems in the route). Note that signing
does not work with lanman or plaintext authentication.
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 9e77145..7fde529 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -36,6 +36,7 @@
#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */
+#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8a2cf12..ec48c96 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -421,6 +421,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",dynperm");
if (m->mnt_sb->s_flags & MS_POSIXACL)
seq_printf(s, ",acl");
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ seq_printf(s, ",mfsymlinks");
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2a43a0a..b3b8752 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -100,6 +100,7 @@ struct smb_vol {
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool fsc:1; /* enable fscache */
+ bool mfsymlinks:1; /* use Minshall+French Symlinks */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
@@ -1343,6 +1344,8 @@ cifs_parse_mount_options(char *options, const char *devname,
"/proc/fs/cifs/LookupCacheEnabled to 0\n");
} else if (strnicmp(data, "fsc", 3) == 0) {
vol->fsc = true;
+ } else if (strnicmp(data, "mfsymlinks", 22) == 0) {
+ vol->mfsymlinks = true;
} else
printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
data);
@@ -2481,6 +2484,14 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cFYI(1, "mounting share using direct i/o");
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
}
+ if (pvolume_info->mfsymlinks) {
+ if (pvolume_info->sfu_emul) {
+ cERROR(1, "mount option mfsymlinks ignored if sfu "
+ "mount option is used");
+ } else {
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
+ }
+ }
if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
cERROR(1, "mount option dynperm ignored if cifsacl "
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
` (5 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 34 ++++++++++++++++++++++++++++++----
1 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 473ca80..2358a5f 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -29,6 +29,24 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+static int
+CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
+ const char *fromName, const char *toName,
+ const struct nls_table *nls_codepage)
+{
+ int rc = -EOPNOTSUPP;
+ return rc;
+}
+
+static int
+CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName, char **symlinkinfo,
+ const struct nls_table *nls_codepage)
+{
+ int rc = -EOPNOTSUPP;
+ return rc;
+}
+
int
cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
@@ -130,7 +148,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
* but there doesn't seem to be any harm in allowing the client to
* read them.
*/
- if (!(tcon->ses->capabilities & CAP_UNIX)) {
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ && !(tcon->ses->capabilities & CAP_UNIX)) {
rc = -EACCES;
goto out;
}
@@ -141,8 +160,12 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
- rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls);
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
+ cifs_sb->local_nls);
+ else
+ rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
+ cifs_sb->local_nls);
kfree(full_path);
out:
if (rc != 0) {
@@ -182,7 +205,10 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
cFYI(1, "symname is %s", symname);
/* BB what if DFS and this volume is on different share? BB */
- if (pTcon->unix_ext)
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+ rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
+ cifs_sb->local_nls);
+ else if (pTcon->unix_ext)
rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls);
/* else
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (2 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
[not found] ` <1280931109-22380-4-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-04 14:11 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
` (4 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/cifsproto.h | 3 +++
fs/cifs/inode.c | 7 +++++++
fs/cifs/link.c | 8 ++++++++
3 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 2eaebbd..e94e095 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
+extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
+ const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid);
#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a15b3a9..c4121de 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
+ /* query for SFU type info if supported and needed */
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
+ tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
+ if (tmprc)
+ cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
+ }
+
if (!*pinode) {
*pinode = cifs_iget(sb, &fattr);
if (!*pinode)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 2358a5f..985373c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -48,6 +48,14 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
}
int
+CIFSCheckMFSymlink(struct cifs_fattr *fattr,
+ const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid)
+{
+ return 0;
+}
+
+int
cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
{
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 4/8] cifs: implement CIFSParseMFSymlink()
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (3 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
` (3 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 985373c..0d90a89 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -28,6 +28,68 @@
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+#include "md5.h"
+
+#define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
+#define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
+#define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
+#define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
+#define CIFS_MF_SYMLINK_FILE_SIZE \
+ (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
+
+#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
+#define CIFS_MF_SYMLINK_MD5_FORMAT \
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
+#define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
+ md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
+ md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
+ md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
+ md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
+
+static int
+CIFSParseMFSymlink(const u8 *buf,
+ unsigned int buf_len,
+ unsigned int *_link_len,
+ char **_link_str)
+{
+ int rc;
+ unsigned int link_len;
+ const char *md5_str1;
+ const char *link_str;
+ struct MD5Context md5_ctx;
+ u8 md5_hash[16];
+ char md5_str2[34];
+
+ if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
+ return -EINVAL;
+
+ md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
+ link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
+
+ rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
+ if (rc != 1)
+ return -EINVAL;
+
+ cifs_MD5_init(&md5_ctx);
+ cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
+ cifs_MD5_final(md5_hash, &md5_ctx);
+
+ snprintf(md5_str2, sizeof(md5_str2),
+ CIFS_MF_SYMLINK_MD5_FORMAT,
+ CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
+
+ if (strncmp(md5_str1, md5_str2, 17) != 0)
+ return -EINVAL;
+
+ if (_link_str) {
+ *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
+ if (!*_link_str)
+ return -ENOMEM;
+ }
+
+ *_link_len = link_len;
+ return 0;
+}
static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 5/8] cifs: implement CIFSCheckMFSymlink()
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (4 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
[not found] ` <1280931109-22380-6-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-04 14:11 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
` (2 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 0d90a89..6cd0879 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -114,6 +114,71 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
{
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ struct cifsTconInfo *pTcon = cifs_sb->tcon;
+ u8 *buf;
+ char *pbuf;
+ unsigned int bytes_read = 0;
+ int buf_type = CIFS_NO_BUFFER;
+ unsigned int link_len = 0;
+ FILE_ALL_INFO file_info;
+
+ if (!(fattr->cf_mode & S_IFREG))
+ /* it's not a symlink */
+ return 0;
+
+ if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
+ /* it's not a symlink */
+ return 0;
+
+ buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ pbuf = buf;
+
+ rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
+ CREATE_NOT_DIR, &netfid, &oplock, &file_info,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+ CIFSSMBClose(xid, pTcon, netfid);
+ kfree(buf);
+ /* it's not a symlink */
+ return 0;
+ }
+
+ /* Read header */
+ rc = CIFSSMBRead(xid, pTcon, netfid,
+ CIFS_MF_SYMLINK_FILE_SIZE /* length */,
+ 0 /* offset */,
+ &bytes_read, &pbuf, &buf_type);
+ CIFSSMBClose(xid, pTcon, netfid);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
+ kfree(buf);
+ if (rc == -EINVAL)
+ /* it's not a symlink */
+ return 0;
+ if (rc != 0)
+ return rc;
+
+ /* it is a symlink */
+ fattr->cf_eof = link_len;
+ fattr->cf_mode &= ~S_IFMT;
+ fattr->cf_mode |= S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
return 0;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 6/8] cifs: implement CIFSQueryMFSymLink()
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (5 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6cd0879..6d00712 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -103,10 +103,54 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
static int
CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, char **symlinkinfo,
- const struct nls_table *nls_codepage)
+ const struct nls_table *nls_codepage, int remap)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ u8 *buf;
+ char *pbuf;
+ unsigned int bytes_read = 0;
+ int buf_type = CIFS_NO_BUFFER;
+ unsigned int link_len = 0;
+ FILE_ALL_INFO file_info;
+
+ buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ pbuf = buf;
+
+ rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
+ CREATE_NOT_DIR, &netfid, &oplock, &file_info,
+ nls_codepage, remap);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+ CIFSSMBClose(xid, tcon, netfid);
+ kfree(buf);
+ /* it's not a symlink */
+ return -EINVAL;
+ }
+
+ rc = CIFSSMBRead(xid, tcon, netfid,
+ CIFS_MF_SYMLINK_FILE_SIZE /* length */,
+ 0 /* offset */,
+ &bytes_read, &pbuf, &buf_type);
+ CIFSSMBClose(xid, tcon, netfid);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
+ kfree(buf);
+ if (rc != 0)
+ return rc;
+
+ return 0;
}
int
@@ -297,7 +341,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls);
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
else
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
cifs_sb->local_nls);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 7/8] cifs: implement CIFSFormatMFSymlink()
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (6 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6d00712..89e09da 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -92,6 +92,48 @@ CIFSParseMFSymlink(const u8 *buf,
}
static int
+CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
+{
+ unsigned int link_len;
+ unsigned int ofs;
+ struct MD5Context md5_ctx;
+ u8 md5_hash[16];
+
+ if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
+ return -EINVAL;
+
+ link_len = strlen(link_str);
+
+ if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
+ return -ENAMETOOLONG;
+
+ cifs_MD5_init(&md5_ctx);
+ cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
+ cifs_MD5_final(md5_hash, &md5_ctx);
+
+ snprintf(buf, buf_len,
+ CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
+ link_len,
+ CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
+
+ ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
+ memcpy(buf + ofs, link_str, link_len);
+
+ ofs += link_len;
+ if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
+ buf[ofs] = '\n';
+ ofs++;
+ }
+
+ while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
+ buf[ofs] = ' ';
+ ofs++;
+ }
+
+ return 0;
+}
+
+static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 8/8] cifs: implement CIFSCreateMFSymLink()
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
` (7 preceding siblings ...)
2010-08-04 14:11 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
@ 2010-08-04 14:11 ` Stefan Metzmacher
8 siblings, 0 replies; 31+ messages in thread
From: Stefan Metzmacher @ 2010-08-04 14:11 UTC (permalink / raw)
To: smfrench-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Stefan Metzmacher
Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
fs/cifs/link.c | 45 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 89e09da..7fecd4f 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -136,10 +136,45 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
- const struct nls_table *nls_codepage)
+ const struct nls_table *nls_codepage, int remap)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc;
+ int oplock = 0;
+ __u16 netfid = 0;
+ u8 *buf;
+ unsigned int bytes_written = 0;
+
+ buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
+ CREATE_NOT_DIR, &netfid, &oplock, NULL,
+ nls_codepage, remap);
+ if (rc != 0) {
+ kfree(buf);
+ return rc;
+ }
+
+ rc = CIFSSMBWrite(xid, tcon, netfid,
+ CIFS_MF_SYMLINK_FILE_SIZE /* length */,
+ 0 /* offset */,
+ &bytes_written, buf, NULL, 0);
+ CIFSSMBClose(xid, tcon, netfid);
+ kfree(buf);
+ if (rc != 0)
+ return rc;
+
+ if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
+ return -EIO;
+
+ return 0;
}
static int
@@ -430,7 +465,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
/* BB what if DFS and this volume is on different share? BB */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
- cifs_sb->local_nls);
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
else if (pTcon->unix_ext)
rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 5/8] cifs: implement CIFSCheckMFSymlink()
[not found] ` <1280931109-22380-6-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-04 14:22 ` Jeff Layton
2010-08-05 12:44 ` Suresh Jayaraman
1 sibling, 0 replies; 31+ messages in thread
From: Jeff Layton @ 2010-08-04 14:22 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On Wed, 4 Aug 2010 16:11:46 +0200
Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/link.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 65 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index 0d90a89..6cd0879 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -114,6 +114,71 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
> const unsigned char *path,
> struct cifs_sb_info *cifs_sb, int xid)
> {
> + int rc;
> + int oplock = 0;
> + __u16 netfid = 0;
> + struct cifsTconInfo *pTcon = cifs_sb->tcon;
> + u8 *buf;
> + char *pbuf;
> + unsigned int bytes_read = 0;
> + int buf_type = CIFS_NO_BUFFER;
> + unsigned int link_len = 0;
> + FILE_ALL_INFO file_info;
> +
> + if (!(fattr->cf_mode & S_IFREG))
> + /* it's not a symlink */
> + return 0;
> +
> + if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
> + /* it's not a symlink */
> + return 0;
> +
> + buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
> + pbuf = buf;
> +
> + rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
> + CREATE_NOT_DIR, &netfid, &oplock, &file_info,
> + cifs_sb->local_nls,
> + cifs_sb->mnt_cifs_flags &
> + CIFS_MOUNT_MAP_SPECIAL_CHR);
> + if (rc != 0) {
> + kfree(buf);
> + return rc;
> + }
> +
> + if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
> + CIFSSMBClose(xid, pTcon, netfid);
> + kfree(buf);
> + /* it's not a symlink */
> + return 0;
> + }
> +
Might be better to move the kmalloc() here. If the open fails, or the
size is wrong you won't need the buffer. Allocating memory can lead to
reclaim events too, so it's best not to do it unless you really need it.
> + /* Read header */
> + rc = CIFSSMBRead(xid, pTcon, netfid,
> + CIFS_MF_SYMLINK_FILE_SIZE /* length */,
> + 0 /* offset */,
> + &bytes_read, &pbuf, &buf_type);
> + CIFSSMBClose(xid, pTcon, netfid);
> + if (rc != 0) {
> + kfree(buf);
> + return rc;
> + }
> +
> + rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
> + kfree(buf);
> + if (rc == -EINVAL)
> + /* it's not a symlink */
> + return 0;
> + if (rc != 0)
> + return rc;
> +
> + /* it is a symlink */
> + fattr->cf_eof = link_len;
> + fattr->cf_mode &= ~S_IFMT;
> + fattr->cf_mode |= S_IFLNK;
> + fattr->cf_dtype = DT_LNK;
> return 0;
> }
>
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <1280931109-22380-4-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-04 14:37 ` Jeff Layton
[not found] ` <20100804103748.521163e6-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
0 siblings, 1 reply; 31+ messages in thread
From: Jeff Layton @ 2010-08-04 14:37 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On Wed, 4 Aug 2010 16:11:44 +0200
Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/cifsproto.h | 3 +++
> fs/cifs/inode.c | 7 +++++++
> fs/cifs/link.c | 8 ++++++++
> 3 files changed, 18 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index 2eaebbd..e94e095 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
> extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
> const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
> extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
> +extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
> + const unsigned char *path,
> + struct cifs_sb_info *cifs_sb, int xid);
> #endif /* _CIFSPROTO_H */
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index a15b3a9..c4121de 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
> cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
>
> + /* query for SFU type info if supported and needed */
> + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
> + tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
> + if (tmprc)
> + cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
> + }
> +
^^^^^^^^^^^^^^
This only seems to touch the codepath without posix extensions. What
about when unix extensions are enabled? The previous patch seems to
indicate that the behavior is that mfsymlinks are always used when that
mount option is used even if unix extensions are enabled. If so, then I
think you'll need a similar change in cifs_get_inode_info_unix.
> if (!*pinode) {
> *pinode = cifs_iget(sb, &fattr);
> if (!*pinode)
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index 2358a5f..985373c 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -48,6 +48,14 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
> }
>
> int
> +CIFSCheckMFSymlink(struct cifs_fattr *fattr,
> + const unsigned char *path,
> + struct cifs_sb_info *cifs_sb, int xid)
> +{
> + return 0;
> +}
> +
> +int
> cifs_hardlink(struct dentry *old_file, struct inode *inode,
> struct dentry *direntry)
> {
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 1/8] cifs: add "mfsymlinks" mount option
[not found] ` <1280847960-16371-2-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-05 11:44 ` Suresh Jayaraman
0 siblings, 0 replies; 31+ messages in thread
From: Suresh Jayaraman @ 2010-08-05 11:44 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 08/03/2010 08:35 PM, Stefan Metzmacher wrote:
> This is the start for an implementation of "Minshall+French Symlinks"
> (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks).
>
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/README | 5 +++++
> fs/cifs/cifs_fs_sb.h | 1 +
> fs/cifs/cifsfs.c | 2 ++
> fs/cifs/connect.c | 11 +++++++++++
> 4 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/README b/fs/cifs/README
> index a727b7c..228c239 100644
> --- a/fs/cifs/README
> +++ b/fs/cifs/README
> @@ -517,6 +517,11 @@ A partial list of the supported mount options follows:
> SFU does). In the future the bottom 9 bits of the
> mode also will be emulated using queries of the security
> descriptor (ACL).
> + mfsymlinks Enable support for Minshall+French symlinks
> + (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks)
> + This option is ignored when specified together with the
> + 'sfu' option. Minshall+French symlinks are used event if
nit.. Did you mean "even" here? ^^^^
> + the server supports the CIFS Unix Extensions.
> sign Must use packet signing (helps avoid unwanted data modification
> by intermediate systems in the route). Note that signing
> does not work with lanman or plaintext authentication.
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 2a43a0a..b3b8752 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -100,6 +100,7 @@ struct smb_vol {
> bool noautotune:1;
> bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
> bool fsc:1; /* enable fscache */
> + bool mfsymlinks:1; /* use Minshall+French Symlinks */
> unsigned int rsize;
> unsigned int wsize;
> bool sockopt_tcp_nodelay:1;
> @@ -1343,6 +1344,8 @@ cifs_parse_mount_options(char *options, const char *devname,
> "/proc/fs/cifs/LookupCacheEnabled to 0\n");
> } else if (strnicmp(data, "fsc", 3) == 0) {
> vol->fsc = true;
> + } else if (strnicmp(data, "mfsymlinks", 22) == 0) {
Why 22 here?
Thanks,
--
Suresh Jayaraman
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs
[not found] ` <1280847960-16371-3-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-05 11:50 ` Suresh Jayaraman
0 siblings, 0 replies; 31+ messages in thread
From: Suresh Jayaraman @ 2010-08-05 11:50 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 08/03/2010 08:35 PM, Stefan Metzmacher wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/link.c | 34 ++++++++++++++++++++++++++++++----
> 1 files changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index 473ca80..2358a5f 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -29,6 +29,24 @@
> #include "cifs_debug.h"
> #include "cifs_fs_sb.h"
>
> +static int
> +CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
> + const char *fromName, const char *toName,
> + const struct nls_table *nls_codepage)
> +{
> + int rc = -EOPNOTSUPP;
> + return rc;
> +}
> +
> +static int
> +CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
> + const unsigned char *searchName, char **symlinkinfo,
> + const struct nls_table *nls_codepage)
> +{
> + int rc = -EOPNOTSUPP;
> + return rc;
> +}
Perhaps these two should be added to cifssmb.c because that is where the
other related functions are defined?
Thanks,
--
Suresh Jayaraman
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <20100804103748.521163e6-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
@ 2010-08-05 12:10 ` Suresh Jayaraman
[not found] ` <4C5AAA3C.1000304-l3A5Bk7waGM@public.gmane.org>
0 siblings, 1 reply; 31+ messages in thread
From: Suresh Jayaraman @ 2010-08-05 12:10 UTC (permalink / raw)
To: Jeff Layton
Cc: Stefan Metzmacher, smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 08/04/2010 08:07 PM, Jeff Layton wrote:
> On Wed, 4 Aug 2010 16:11:44 +0200
> Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>
>> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
>> ---
>> fs/cifs/cifsproto.h | 3 +++
>> fs/cifs/inode.c | 7 +++++++
>> fs/cifs/link.c | 8 ++++++++
>> 3 files changed, 18 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>> index 2eaebbd..e94e095 100644
>> --- a/fs/cifs/cifsproto.h
>> +++ b/fs/cifs/cifsproto.h
>> @@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
>> extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
>> const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
>> extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
>> +extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
>> + const unsigned char *path,
>> + struct cifs_sb_info *cifs_sb, int xid);
>> #endif /* _CIFSPROTO_H */
>> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>> index a15b3a9..c4121de 100644
>> --- a/fs/cifs/inode.c
>> +++ b/fs/cifs/inode.c
>> @@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
>> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
>> cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
>>
>> + /* query for SFU type info if supported and needed */
>> + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
>> + tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
>> + if (tmprc)
>> + cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
>> + }
>> +
>
> ^^^^^^^^^^^^^^
>
> This only seems to touch the codepath without posix extensions. What
> about when unix extensions are enabled? The previous patch seems to
> indicate that the behavior is that mfsymlinks are always used when that
> mount option is used even if unix extensions are enabled. If so, then I
> think you'll need a similar change in cifs_get_inode_info_unix.
>
I initially thought so. But, looking again - there is no point in
querying for SFU type info if unix extensions are enabled..?
Thanks,
--
Suresh Jayaraman
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <4C5AAA3C.1000304-l3A5Bk7waGM@public.gmane.org>
@ 2010-08-05 12:31 ` Jeff Layton
[not found] ` <20100805083113.2e7bfbb9-xSBYVWDuneFaJnirhKH9O4GKTjYczspe@public.gmane.org>
0 siblings, 1 reply; 31+ messages in thread
From: Jeff Layton @ 2010-08-05 12:31 UTC (permalink / raw)
To: Suresh Jayaraman
Cc: Stefan Metzmacher, smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On Thu, 05 Aug 2010 17:40:36 +0530
Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> On 08/04/2010 08:07 PM, Jeff Layton wrote:
> > On Wed, 4 Aug 2010 16:11:44 +0200
> > Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> >
> >> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> >> ---
> >> fs/cifs/cifsproto.h | 3 +++
> >> fs/cifs/inode.c | 7 +++++++
> >> fs/cifs/link.c | 8 ++++++++
> >> 3 files changed, 18 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> >> index 2eaebbd..e94e095 100644
> >> --- a/fs/cifs/cifsproto.h
> >> +++ b/fs/cifs/cifsproto.h
> >> @@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
> >> extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
> >> const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
> >> extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
> >> +extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
> >> + const unsigned char *path,
> >> + struct cifs_sb_info *cifs_sb, int xid);
> >> #endif /* _CIFSPROTO_H */
> >> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> >> index a15b3a9..c4121de 100644
> >> --- a/fs/cifs/inode.c
> >> +++ b/fs/cifs/inode.c
> >> @@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
> >> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
> >> cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
> >>
> >> + /* query for SFU type info if supported and needed */
> >> + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
> >> + tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
> >> + if (tmprc)
> >> + cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
> >> + }
> >> +
> >
> > ^^^^^^^^^^^^^^
> >
> > This only seems to touch the codepath without posix extensions. What
> > about when unix extensions are enabled? The previous patch seems to
> > indicate that the behavior is that mfsymlinks are always used when that
> > mount option is used even if unix extensions are enabled. If so, then I
> > think you'll need a similar change in cifs_get_inode_info_unix.
> >
>
> I initially thought so. But, looking again - there is no point in
> querying for SFU type info if unix extensions are enabled..?
>
> Thanks,
>
I'm not sure that addresses the concern. It's very confusing, but:
SFU != POSIX extensions
The SFU codepath goes through the "normal" cifs code
(cifs_get_inode_info). The POSIX extensions codepath goes through a
different codepath (cifs_get_inode_info_unix). Yes, all of this is
sorely in need of being cleaned up, but that's the way it works today...
Metze's patches seem to indicate that mfsymlinks and unix extensions
aren't mutually exclusive. The unix codepaths that determine inode
type and fill out inode data should be using the mfsymlink stuff too.
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/8] cifs: implement CIFSCheckMFSymlink()
[not found] ` <1280931109-22380-6-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-04 14:22 ` Jeff Layton
@ 2010-08-05 12:44 ` Suresh Jayaraman
[not found] ` <4C5AB228.90800-l3A5Bk7waGM@public.gmane.org>
1 sibling, 1 reply; 31+ messages in thread
From: Suresh Jayaraman @ 2010-08-05 12:44 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 08/04/2010 07:41 PM, Stefan Metzmacher wrote:
> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> fs/cifs/link.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 65 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index 0d90a89..6cd0879 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -114,6 +114,71 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
> const unsigned char *path,
> struct cifs_sb_info *cifs_sb, int xid)
> {
> + int rc;
> + int oplock = 0;
> + __u16 netfid = 0;
> + struct cifsTconInfo *pTcon = cifs_sb->tcon;
> + u8 *buf;
> + char *pbuf;
> + unsigned int bytes_read = 0;
> + int buf_type = CIFS_NO_BUFFER;
> + unsigned int link_len = 0;
> + FILE_ALL_INFO file_info;
> +
> + if (!(fattr->cf_mode & S_IFREG))
> + /* it's not a symlink */
> + return 0;
Perhaps a little naive - what if cf_mode is S_IFDIR?
Thanks,
--
Suresh Jayaraman
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/8] cifs: implement CIFSCheckMFSymlink()
[not found] ` <4C5AB228.90800-l3A5Bk7waGM@public.gmane.org>
@ 2010-08-05 15:47 ` Stefan (metze) Metzmacher
0 siblings, 0 replies; 31+ messages in thread
From: Stefan (metze) Metzmacher @ 2010-08-05 15:47 UTC (permalink / raw)
To: Suresh Jayaraman
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 1120 bytes --]
Am 05.08.2010 14:44, schrieb Suresh Jayaraman:
> On 08/04/2010 07:41 PM, Stefan Metzmacher wrote:
>> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
>> ---
>> fs/cifs/link.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 65 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
>> index 0d90a89..6cd0879 100644
>> --- a/fs/cifs/link.c
>> +++ b/fs/cifs/link.c
>> @@ -114,6 +114,71 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
>> const unsigned char *path,
>> struct cifs_sb_info *cifs_sb, int xid)
>> {
>> + int rc;
>> + int oplock = 0;
>> + __u16 netfid = 0;
>> + struct cifsTconInfo *pTcon = cifs_sb->tcon;
>> + u8 *buf;
>> + char *pbuf;
>> + unsigned int bytes_read = 0;
>> + int buf_type = CIFS_NO_BUFFER;
>> + unsigned int link_len = 0;
>> + FILE_ALL_INFO file_info;
>> +
>> + if (!(fattr->cf_mode & S_IFREG))
>> + /* it's not a symlink */
>> + return 0;
>
> Perhaps a little naive - what if cf_mode is S_IFDIR?
Then it's a directory and not a symlink.
metze
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <20100805083113.2e7bfbb9-xSBYVWDuneFaJnirhKH9O4GKTjYczspe@public.gmane.org>
@ 2010-08-09 14:04 ` Stefan (metze) Metzmacher
[not found] ` <4C600AEA.607-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
0 siblings, 1 reply; 31+ messages in thread
From: Stefan (metze) Metzmacher @ 2010-08-09 14:04 UTC (permalink / raw)
To: Jeff Layton
Cc: Suresh Jayaraman, smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 5041 bytes --]
Hi,
I noticed that I also need to hook the cifs_readdir() path.
Can someone tell me how I can construct the file name
relative to the mount point. The TODO in this change.
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -679,7 +679,7 @@ static int cifs_get_name_from_search_buf(struct qstr
*pqst,
return rc;
}
-static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t
filldir,
+static int cifs_filldir(int xid, char *pfindEntry, struct file *file,
filldir_t filldir,
void *direntry, char *scratch_buf, unsigned int
max_len)
{
int rc = 0;
@@ -731,6 +731,15 @@ static int cifs_filldir(char *pfindEntry, struct
file *file, filldir_t filldir,
cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
pfindEntry, cifs_sb);
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
+ int tmprc;
+ const char *full_path = qstring.name;
+ /* TODO: build full path relative to the mount point */
+ tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
+ if (tmprc)
+ cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
+ }
+
if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
fattr.cf_uniqueid = inum;
} else {
@@ -856,7 +865,7 @@ int cifs_readdir(struct file *file, void *direntry,
filldir_t filldir)
}
/* if buggy server returns . and .. late do
we want to check for that here? */
- rc = cifs_filldir(current_entry, file,
+ rc = cifs_filldir(xid, current_entry, file,
filldir, direntry, tmp_buf,
max_len);
if (rc == -EOVERFLOW) {
rc = 0;
metze
Am 05.08.2010 14:31, schrieb Jeff Layton:
> On Thu, 05 Aug 2010 17:40:36 +0530
> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
>
>> On 08/04/2010 08:07 PM, Jeff Layton wrote:
>>> On Wed, 4 Aug 2010 16:11:44 +0200
>>> Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
>>>
>>>> Signed-off-by: Stefan Metzmacher <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
>>>> ---
>>>> fs/cifs/cifsproto.h | 3 +++
>>>> fs/cifs/inode.c | 7 +++++++
>>>> fs/cifs/link.c | 8 ++++++++
>>>> 3 files changed, 18 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>>>> index 2eaebbd..e94e095 100644
>>>> --- a/fs/cifs/cifsproto.h
>>>> +++ b/fs/cifs/cifsproto.h
>>>> @@ -409,4 +409,7 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
>>>> extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
>>>> const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
>>>> extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
>>>> +extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
>>>> + const unsigned char *path,
>>>> + struct cifs_sb_info *cifs_sb, int xid);
>>>> #endif /* _CIFSPROTO_H */
>>>> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>>>> index a15b3a9..c4121de 100644
>>>> --- a/fs/cifs/inode.c
>>>> +++ b/fs/cifs/inode.c
>>>> @@ -661,6 +661,13 @@ int cifs_get_inode_info(struct inode **pinode,
>>>> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
>>>> cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
>>>>
>>>> + /* query for SFU type info if supported and needed */
>>>> + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
>>>> + tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
>>>> + if (tmprc)
>>>> + cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
>>>> + }
>>>> +
>>>
>>> ^^^^^^^^^^^^^^
>>>
>>> This only seems to touch the codepath without posix extensions. What
>>> about when unix extensions are enabled? The previous patch seems to
>>> indicate that the behavior is that mfsymlinks are always used when that
>>> mount option is used even if unix extensions are enabled. If so, then I
>>> think you'll need a similar change in cifs_get_inode_info_unix.
>>>
>>
>> I initially thought so. But, looking again - there is no point in
>> querying for SFU type info if unix extensions are enabled..?
>>
>> Thanks,
>>
>
> I'm not sure that addresses the concern. It's very confusing, but:
>
> SFU != POSIX extensions
>
> The SFU codepath goes through the "normal" cifs code
> (cifs_get_inode_info). The POSIX extensions codepath goes through a
> different codepath (cifs_get_inode_info_unix). Yes, all of this is
> sorely in need of being cleaned up, but that's the way it works today...
>
> Metze's patches seem to indicate that mfsymlinks and unix extensions
> aren't mutually exclusive. The unix codepaths that determine inode
> type and fill out inode data should be using the mfsymlink stuff too.
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub
[not found] ` <4C600AEA.607-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2010-08-09 14:16 ` Suresh Jayaraman
0 siblings, 0 replies; 31+ messages in thread
From: Suresh Jayaraman @ 2010-08-09 14:16 UTC (permalink / raw)
To: Stefan (metze) Metzmacher
Cc: Jeff Layton, smfrench-Re5JQEeQqe8AvxtiuMwx3w,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 08/09/2010 07:34 PM, Stefan (metze) Metzmacher wrote:
> Hi,
>
> I noticed that I also need to hook the cifs_readdir() path.
>
> Can someone tell me how I can construct the file name
> relative to the mount point. The TODO in this change.
build_path_from_dentry() ?
--
Suresh Jayaraman
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2010-08-09 14:16 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-03 15:05 [CIFS] Support for Minshall+French symlinks Stefan Metzmacher
[not found] ` <1280847960-16371-1-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:05 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
[not found] ` <1280847960-16371-2-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-05 11:44 ` Suresh Jayaraman
2010-08-03 15:05 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
[not found] ` <1280847960-16371-3-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-05 11:50 ` Suresh Jayaraman
2010-08-03 15:05 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
2010-08-03 15:05 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
[not found] ` <1280847960-16371-7-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 16:31 ` Jeff Layton
2010-08-03 15:05 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
2010-08-03 15:06 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
[not found] ` <1280847960-16371-9-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-03 15:29 ` Jeff Layton
2010-08-03 18:00 ` [CIFS] Support for Minshall+French symlinks Steve French
[not found] ` <AANLkTinJ1WRBT_Q3TqOZdMQExV66LSUAPG4c01yK-XRK-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-08-04 14:11 ` Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 1/8] cifs: add "mfsymlinks" mount option Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 2/8] cifs: add CIFSCreateMFSymLink() and CIFSQueryMFSymLink() as stubs Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 3/8] cifs: add CIFSCheckMFSymlink() as stub Stefan Metzmacher
[not found] ` <1280931109-22380-4-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-04 14:37 ` Jeff Layton
[not found] ` <20100804103748.521163e6-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2010-08-05 12:10 ` Suresh Jayaraman
[not found] ` <4C5AAA3C.1000304-l3A5Bk7waGM@public.gmane.org>
2010-08-05 12:31 ` Jeff Layton
[not found] ` <20100805083113.2e7bfbb9-xSBYVWDuneFaJnirhKH9O4GKTjYczspe@public.gmane.org>
2010-08-09 14:04 ` Stefan (metze) Metzmacher
[not found] ` <4C600AEA.607-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-09 14:16 ` Suresh Jayaraman
2010-08-04 14:11 ` [PATCH 4/8] cifs: implement CIFSParseMFSymlink() Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 5/8] cifs: implement CIFSCheckMFSymlink() Stefan Metzmacher
[not found] ` <1280931109-22380-6-git-send-email-metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2010-08-04 14:22 ` Jeff Layton
2010-08-05 12:44 ` Suresh Jayaraman
[not found] ` <4C5AB228.90800-l3A5Bk7waGM@public.gmane.org>
2010-08-05 15:47 ` Stefan (metze) Metzmacher
2010-08-04 14:11 ` [PATCH 6/8] cifs: implement CIFSQueryMFSymLink() Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 7/8] cifs: implement CIFSFormatMFSymlink() Stefan Metzmacher
2010-08-04 14:11 ` [PATCH 8/8] cifs: implement CIFSCreateMFSymLink() Stefan Metzmacher
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).