s3: vfs_streams_depot: add delete_lost option
authorBjörn Baumbach <bb@sernet.de>
Thu, 27 Sep 2012 10:40:47 +0000 (12:40 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 1 Oct 2012 16:47:30 +0000 (18:47 +0200)
With this option lost stream directories will be removed
instead of renamed.

Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Mon Oct  1 18:47:30 CEST 2012 on sn-devel-104

source3/modules/vfs_streams_depot.c

index c0d5945382e740354317ee83fc640815e5723da3..620a58075383cba8aade1362ac3fa550415cc0d4 100644 (file)
@@ -198,6 +198,7 @@ static char *stream_dir(vfs_handle_struct *handle,
        if (SMB_VFS_NEXT_STAT(handle, smb_fname_hash) == 0) {
                struct smb_filename *smb_fname_new = NULL;
                char *newname;
+               bool delete_lost;
 
                if (!S_ISDIR(smb_fname_hash->st.st_ex_mode)) {
                        errno = EINVAL;
@@ -211,36 +212,54 @@ static char *stream_dir(vfs_handle_struct *handle,
 
                /*
                 * Someone has recreated a file under an existing inode
-                * without deleting the streams directory. For now, just move
-                * it away.
+                * without deleting the streams directory.
+                * Move it away or remove if streams_depot:delete_lost is set.
                 */
 
        again:
-               newname = talloc_asprintf(talloc_tos(), "lost-%lu", random());
-               if (newname == NULL) {
-                       errno = ENOMEM;
-                       goto fail;
-               }
+               delete_lost = lp_parm_bool(SNUM(handle->conn), "streams_depot",
+                                          "delete_lost", false);
+
+               if (delete_lost) {
+                       DEBUG(3, ("Someone has recreated a file under an "
+                             "existing inode. Removing: %s\n",
+                             smb_fname_hash->base_name));
+                       recursive_rmdir(talloc_tos(), handle->conn,
+                                       smb_fname_hash);
+                       SMB_VFS_NEXT_RMDIR(handle, smb_fname_hash->base_name);
+               } else {
+                       newname = talloc_asprintf(talloc_tos(), "lost-%lu",
+                                                 random());
+                       DEBUG(3, ("Someone has recreated a file under an "
+                             "existing inode. Renaming: %s to: %s\n",
+                             smb_fname_hash->base_name,
+                             newname));
+                       if (newname == NULL) {
+                               errno = ENOMEM;
+                               goto fail;
+                       }
 
-               status = create_synthetic_smb_fname(talloc_tos(), newname,
-                                                   NULL, NULL,
-                                                   &smb_fname_new);
-               TALLOC_FREE(newname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       goto fail;
-               }
+                       status = create_synthetic_smb_fname(talloc_tos(),
+                                                           newname,
+                                                           NULL, NULL,
+                                                           &smb_fname_new);
+                       TALLOC_FREE(newname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               errno = map_errno_from_nt_status(status);
+                               goto fail;
+                       }
 
-               if (SMB_VFS_NEXT_RENAME(handle, smb_fname_hash,
-                                       smb_fname_new) == -1) {
-                       TALLOC_FREE(smb_fname_new);
-                       if ((errno == EEXIST) || (errno == ENOTEMPTY)) {
-                               goto again;
+                       if (SMB_VFS_NEXT_RENAME(handle, smb_fname_hash,
+                                               smb_fname_new) == -1) {
+                               TALLOC_FREE(smb_fname_new);
+                               if ((errno == EEXIST) || (errno == ENOTEMPTY)) {
+                                       goto again;
+                               }
+                               goto fail;
                        }
-                       goto fail;
-               }
 
-               TALLOC_FREE(smb_fname_new);
+                       TALLOC_FREE(smb_fname_new);
+               }
        }
 
        if (!create_it) {