All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v3] cifs: Add support of Alternate Data Streams
Date: Wed, 10 Oct 2012 12:14:35 -0400	[thread overview]
Message-ID: <20121010121435.124d9ce5@corrin.poochiereds.net> (raw)
In-Reply-To: <1349881906-9791-1-git-send-email-shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Wed, 10 Oct 2012 10:11:46 -0500
shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:

> From: Shirish Pargaonkar <shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> 
> 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 stream file and stream type are specified using : after the file name,
> so that is used to differentiate between a regular file and its
> alternate data streams and stream types.
> Since they all have the same file id, each path name,
> file name:stream name:stream type, has a separate inode with that same
> file id but a distinct private data (path name) in that inode to
> distinguish them.
> 
> This scheme applies only to non-posix compliant servers such as Windows.
> 
> One operation that does not work is Rename (0x7).
> 
> 
> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  fs/cifs/cifsfs.c   |    1 +
>  fs/cifs/cifsglob.h |    2 ++
>  fs/cifs/inode.c    |   33 ++++++++++++++++++++++++++++++++-
>  3 files changed, 35 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index e7931cc..3068992 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -264,6 +264,7 @@ cifs_evict_inode(struct inode *inode)
>  {
>  	truncate_inode_pages(&inode->i_data, 0);
>  	clear_inode(inode);
> +	kfree(inode->i_private);
>  	cifs_fscache_release_inode_cookie(inode);
>  }
>  
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index f5af252..26d65c7 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -1251,6 +1251,7 @@ struct dfs_info3_param {
>  #define CIFS_FATTR_DELETE_PENDING	0x2
>  #define CIFS_FATTR_NEED_REVAL		0x4
>  #define CIFS_FATTR_INO_COLLISION	0x8
> +#define CIFS_FATTR_ALTDATASTR		0x10
>  
>  struct cifs_fattr {
>  	u32		cf_flags;
> @@ -1268,6 +1269,7 @@ struct cifs_fattr {
>  	struct timespec	cf_atime;
>  	struct timespec	cf_mtime;
>  	struct timespec	cf_ctime;
> +	char		*cf_private;
>  };
>  
>  static inline void free_dfs_info_param(struct dfs_info3_param *param)
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index afdff79..93b010b 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -619,6 +619,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
>  	struct cifs_fattr fattr;
>  	struct cifs_search_info *srchinf = NULL;
>  
> +	fattr.cf_private = NULL;
>  	tlink = cifs_sb_tlink(cifs_sb);
>  	if (IS_ERR(tlink))
>  		return PTR_ERR(tlink);
> @@ -746,14 +747,34 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
>  	}
>  
>  	if (!*inode) {
> +		if (strstr(full_path, ":")) {
> +			fattr.cf_private = kstrdup(full_path, GFP_KERNEL);
> +			if (!fattr.cf_private) {
> +				rc = -ENOMEM;
> +				goto cgii_exit;
> +			}
> +			fattr.cf_flags |= CIFS_FATTR_ALTDATASTR;
> +		}
> +
>  		*inode = cifs_iget(sb, &fattr);
> -		if (!*inode)
> +		if (*inode) {
> +			if (strstr(full_path, ":") &&
> +					!((*inode)->i_flags & S_PRIVATE)) {
> +				(*inode)->i_private = kstrdup(fattr.cf_private,
> +							GFP_KERNEL);
> +				if ((*inode)->i_private)
> +					(*inode)->i_flags |= S_PRIVATE;
> +				else
> +					rc = -ENOMEM;
> +			}
> +		} else
>  			rc = -ENOMEM;
>  	} else {
>  		cifs_fattr_to_inode(*inode, &fattr);
>  	}
>  
>  cgii_exit:
> +	kfree(fattr.cf_private);
>  	kfree(buf);
>  	cifs_put_tlink(tlink);
>  	return rc;
> @@ -784,6 +805,16 @@ cifs_find_inode(struct inode *inode, void *opaque)
>  	if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
>  		fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
>  
> +	/* looking for an inode of a alternate data stream (full pathname) */
> +	if (fattr->cf_flags & CIFS_FATTR_ALTDATASTR) {
> +		if (!(inode->i_flags & S_PRIVATE)) {
> +			return 0;
> +		} else {
> +			if (strcmp(inode->i_private, fattr->cf_private))
> +				return 0;
> +		}
> +	}
> +
>  	return 1;
>  }
>  

I have real doubts as to whether this patch is necessary. Here's why:

AIUI, the main concern is that you'll open the "normal" data stream on
the file, cache a bunch of data. Then, if you open the alternate
datastream, the kernel will see that as the same inode -- it'll look
like a hardlink. Then when you go to read, you'll get back the cached
data from the original datastream instead of the alternate one.

The key point that's missing here is that servers do not hand out
oplocks for alternate data streams. As long as you've mounted in
cache=strict mode (which is the default for 3.7), then there should be
no problem at all, right?

When you go to open the alternate data stream, it won't matter if the
original datastream had a bunch of data cached. You'll have no oplock
for the file anymore and so you'll if effect be doing DIO to the server
for the alternate datastream anyway.

The only remaining question I have is whether the servers issue oplock
breaks for the "normal" datastream when an alternate datastream is
opened. For instance, suppose I do the following pseudocode:

normal = open("file", ...);

...server issues an oplock for the open. If I then I do:

alternate = open("file:alternate", ...);

...does the server issue an oplock break for the original oplock prior
to performing second open?

-- 
Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

  parent reply	other threads:[~2012-10-10 16:14 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-10 15:11 [PATCH v3] cifs: Add support of Alternate Data Streams shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w
     [not found] ` <1349881906-9791-1-git-send-email-shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-10-10 16:14   ` Jeff Layton [this message]
     [not found]     ` <20121010121435.124d9ce5-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2012-10-10 17:22       ` Shirish Pargaonkar
2012-10-10 17:25         ` Jeff Layton
     [not found]           ` <20121010132559.0634822b-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2012-10-10 19:05             ` Jeff Layton
     [not found]               ` <20121010150549.273d797c-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2012-10-10 19:19                 ` Shirish Pargaonkar
2012-10-10 21:40                 ` Shirish Pargaonkar
2012-10-11  5:33                 ` Shirish Pargaonkar
     [not found]                   ` <CADT32eLsqrijHR_1TtD5isBwJmDzt=ScWzPNbsL3R_x41HWmTA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-11 17:54                     ` Jeff Layton
     [not found]                       ` <20121011135434.1ec51a10-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2012-10-11 19:02                         ` Shirish Pargaonkar
     [not found]                           ` <CADT32eL44krnu0romJKA3d3mErVP2pefJWj3N_mdUpSGvOjB1Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-11 19:12                             ` Jeff Layton
2012-10-10 22:59             ` Jeremy Allison

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=20121010121435.124d9ce5@corrin.poochiereds.net \
    --to=jlayton-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.