diff mbox

[V2] cifs: Add support of Alternate Data Streams

Message ID 1347764747-16822-1-git-send-email-shirishpargaonkar@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shirish Pargaonkar Sept. 16, 2012, 3:05 a.m. UTC
From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>


Add support of Alternate Data Streams (ads).

The generic access flags that cifs client currently employs are sufficient
for alternate data streams as well (MS-CIFS 2.2.4.64.1).

The ads files have a : in the name, so that is used to differentiate
between a regular file and its alternate data streams as they
have the same file id.
This scheme applies to non-posix compliant servers such as Windows only.

One operation that does not work is Rename (0x7).


Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
---
 fs/cifs/inode.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

Comments

Jeff Layton Sept. 16, 2012, 10:59 a.m. UTC | #1
On Sat, 15 Sep 2012 22:05:47 -0500
shirishpargaonkar@gmail.com wrote:

> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> 
> 
> Add support of Alternate Data Streams (ads).
> 
> The generic access flags that cifs client currently employs are sufficient
> for alternate data streams as well (MS-CIFS 2.2.4.64.1).
> 
> The ads files have a : in the name, so that is used to differentiate
> between a regular file and its alternate data streams as they
> have the same file id.
> This scheme applies to non-posix compliant servers such as Windows only.
> 
> One operation that does not work is Rename (0x7).
> 
> 
> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> ---
>  fs/cifs/inode.c |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index cb79c7e..a28950a 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -709,10 +709,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
>  			cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
>  	}
>  
> +	if (strstr(full_path, ":"))
> +		fattr.cf_flags |= S_PRIVATE;
> +

While S_PRIVATE doesn't conflict with any of the other cf_flag values
currently, I think it would be best to define a new CIFS_FATTR_* flag
for this purpose.

>  	if (!*inode) {
>  		*inode = cifs_iget(sb, &fattr);
>  		if (!*inode)
>  			rc = -ENOMEM;
> +		else
> +			(*inode)->i_flags |= fattr.cf_flags;

Uhh no...these flags have nothing to do with the i_flags. This will
almost certainly break things.

>  	} else {
>  		cifs_fattr_to_inode(*inode, &fattr);
>  	}
> @@ -744,6 +749,10 @@ cifs_find_inode(struct inode *inode, void *opaque)
>  	if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
>  		return 0;
>  
> +	/* don't match inode with different flags */
> +	if ((inode->i_flags & S_PRIVATE) != (fattr->cf_flags & S_PRIVATE))
> +		return 0;
> +
>  	/* if it's not a directory or has no dentries, then flag it */
>  	if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
>  		fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;

I'm still trying to understand the point of this patch. I guess the
concern is that these files have the same uniqueid? So this will look
like a hardlinked file metadata-wise, but will have different contents?

If so, then isn't it possible that you'd have more than one alternate
data stream attached to the file? In that case, it looks like the
approach you're using here won't work since you're only designating the
alternate data stream with a single flag value.
Shirish Pargaonkar Sept. 16, 2012, 2:49 p.m. UTC | #2
On Sun, Sep 16, 2012 at 5:59 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Sat, 15 Sep 2012 22:05:47 -0500
> shirishpargaonkar@gmail.com wrote:
>
>> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>
>>
>> Add support of Alternate Data Streams (ads).
>>
>> The generic access flags that cifs client currently employs are sufficient
>> for alternate data streams as well (MS-CIFS 2.2.4.64.1).
>>
>> The ads files have a : in the name, so that is used to differentiate
>> between a regular file and its alternate data streams as they
>> have the same file id.
>> This scheme applies to non-posix compliant servers such as Windows only.
>>
>> One operation that does not work is Rename (0x7).
>>
>>
>> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> ---
>>  fs/cifs/inode.c |    9 +++++++++
>>  1 files changed, 9 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>> index cb79c7e..a28950a 100644
>> --- a/fs/cifs/inode.c
>> +++ b/fs/cifs/inode.c
>> @@ -709,10 +709,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
>>                       cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
>>       }
>>
>> +     if (strstr(full_path, ":"))
>> +             fattr.cf_flags |= S_PRIVATE;
>> +
>
> While S_PRIVATE doesn't conflict with any of the other cf_flag values
> currently, I think it would be best to define a new CIFS_FATTR_* flag
> for this purpose.
>
>>       if (!*inode) {
>>               *inode = cifs_iget(sb, &fattr);
>>               if (!*inode)
>>                       rc = -ENOMEM;
>> +             else
>> +                     (*inode)->i_flags |= fattr.cf_flags;
>
> Uhh no...these flags have nothing to do with the i_flags. This will
> almost certainly break things.
>
>>       } else {
>>               cifs_fattr_to_inode(*inode, &fattr);
>>       }
>> @@ -744,6 +749,10 @@ cifs_find_inode(struct inode *inode, void *opaque)
>>       if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
>>               return 0;
>>
>> +     /* don't match inode with different flags */
>> +     if ((inode->i_flags & S_PRIVATE) != (fattr->cf_flags & S_PRIVATE))
>> +             return 0;
>> +
>>       /* if it's not a directory or has no dentries, then flag it */
>>       if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
>>               fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
>
> I'm still trying to understand the point of this patch. I guess the
> concern is that these files have the same uniqueid? So this will look
> like a hardlinked file metadata-wise, but will have different contents?
>
> If so, then isn't it possible that you'd have more than one alternate
> data stream attached to the file? In that case, it looks like the
> approach you're using here won't work since you're only designating the
> alternate data stream with a single flag value.
>
> --
> Jeff Layton <jlayton@samba.org>

Jeff, yes, realized that after posting the patch.  Will work on fixing
that and other comments.

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index cb79c7e..a28950a 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -709,10 +709,15 @@  cifs_get_inode_info(struct inode **inode, const char *full_path,
 			cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
 	}
 
+	if (strstr(full_path, ":"))
+		fattr.cf_flags |= S_PRIVATE;
+
 	if (!*inode) {
 		*inode = cifs_iget(sb, &fattr);
 		if (!*inode)
 			rc = -ENOMEM;
+		else
+			(*inode)->i_flags |= fattr.cf_flags;
 	} else {
 		cifs_fattr_to_inode(*inode, &fattr);
 	}
@@ -744,6 +749,10 @@  cifs_find_inode(struct inode *inode, void *opaque)
 	if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
 		return 0;
 
+	/* don't match inode with different flags */
+	if ((inode->i_flags & S_PRIVATE) != (fattr->cf_flags & S_PRIVATE))
+		return 0;
+
 	/* if it's not a directory or has no dentries, then flag it */
 	if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
 		fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;