[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mv does not behave like Solaris mv with respect to directory content

From: Haynes, Tom
Subject: Re: mv does not behave like Solaris mv with respect to directory contents
Date: Thu, 26 Sep 2002 08:48:02 -0700 (PDT)

As a followup, I've not seen a reply. ;>

Here is a diff of my hack to get this working:

cetialpha5.eng.netapp.com:> diff copy.c ../../fileutils-4.1.stock/src/copy.c
<         const struct cp_options *x, int *copy_into_self, int move_mode)
>         const struct cp_options *x, int *copy_into_self)
<                           ancestors, &non_command_line_options, move_mode,
>                           ancestors, &non_command_line_options, 0,
<                   copy_into_self, move_mode))
>                   copy_into_self))

> I've looked at traces of both Solaris mv and the cut and paste GUI operation
> on windows for behavior when a directory is moved.  In both cases, if
> the rename of the directory failed, then it is copied and then the entries
> are moved across one by one.  Both approaches try a move and not a copy.
> In the GNU mv, if the directory rename fails, then the entries are all
> copied and no attempt is made to move them across.  As an optimization,
> I see why that would be there.  However, it does yield different behavior
> than other platforms.
> In NetApp's NFS file servers, we have the concept of a quota tree, qtree, 
> which
> is a combination of a logical partition and quotas on a rooted subtree
> of a volume.  In the past, we disallowed moving files across qtrees. In
> our next release, we are going to allow moving files, but not directories,
> across qtrees.  With the typical client implementation of mv, the
> rename of the directory fails, so it gets copied to the new qtree,
> and then recursion tries to rename the files.  They get renamed and
> finally the original directory gets deleted.
> This will not work with the 4.1 version of fileutils.
> If I look in the source, I see:
> int
> copy (const char *src_path, const char *dst_path,
>       int nonexistent_dst, const struct cp_options *options,
>       int *copy_into_self, int *rename_succeeded)
> {
>   /* move_mode is set to the value from the `options' parameter for the
>      first copy_internal call.  For all subsequent calls (if any), it must
>      be zero.  */
>   int move_mode = options->move_mode;
>   assert (valid_options (options));
>   /* Record the file names: they're used in case of error, when copying
>      a directory into itself.  I don't like to make these tools do *any*
>      extra work in the common case when that work is solely to handle
>      exceptional cases, but in this case, I don't see a way to derive the
>      top level source and destination directory names where they're used.
>      An alternative is to use COPY_INTO_SELF and print the diagnostic
>      from every caller -- but I don't wan't to do that.  */
>   top_level_src_path = src_path;
>   top_level_dst_path = dst_path;
>   return copy_internal (src_path, dst_path, nonexistent_dst, 0, NULL,
>                         options, move_mode, copy_into_self, rename_succeeded);
> }
> Later, inside copy_dir:
>       ret |= copy_internal (src_path, dst_path, new_dst, src_sb->st_dev,
>                             ancestors, &non_command_line_options, 0,
>                             &local_copy_into_self, NULL);
> One solution is to pass move_mode to copy_dir and let it follow the
> recursion.  The second is to change all references to move_mode to
> be to options->move_mode and remove the move_mode parameter.
> I can provide network trace files of the different client mvs.
> --
> Tom Haynes, cfb
> address@hidden

Tom Haynes, cfb

reply via email to

[Prev in Thread] Current Thread [Next in Thread]