handle large directories in smb2_deltree()
authorAndrew Tridgell <tridge@samba.org>
Wed, 5 Aug 2009 05:05:13 +0000 (15:05 +1000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 5 Aug 2009 05:05:13 +0000 (15:05 +1000)
source4/libcli/smb2/util.c

index a360d8fbdff3c357946dd6cb240659ce3da8f4dd..8602c91a9f670f28f7474a030f7589ce0239a17f 100644 (file)
@@ -113,6 +113,7 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
        TALLOC_CTX *tmp_ctx = talloc_new(tree);
        struct smb2_find f;
        struct smb2_create create_parm;
+       bool did_delete;
 
        /* it might be a file */
        status = smb2_util_unlink(tree, dname);
@@ -154,45 +155,50 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
        }
        
 
-       ZERO_STRUCT(f);
-       f.in.file.handle       = create_parm.out.file.handle;
-       f.in.max_response_size = 0x10000;
-       f.in.level             = SMB2_FIND_NAME_INFO;
-       f.in.pattern           = "*";
-
-       status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
-       if (NT_STATUS_IS_ERR(status)) {
-               DEBUG(2,("Failed to list %s - %s\n", 
-                        dname, nt_errstr(status)));
-               smb2_util_close(tree, create_parm.out.file.handle);
-               talloc_free(tmp_ctx);
-               return -1;
-       }
-
-       for (i=0;i<count;i++) {
-               char *name;
-               if (strcmp(".", list[i].name_info.name.s) == 0 ||
-                   strcmp("..", list[i].name_info.name.s) == 0) {
-                       continue;
+       do {
+               did_delete = false;
+
+               ZERO_STRUCT(f);
+               f.in.file.handle       = create_parm.out.file.handle;
+               f.in.max_response_size = 0x10000;
+               f.in.level             = SMB2_FIND_NAME_INFO;
+               f.in.pattern           = "*";
+               
+               status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
+               if (NT_STATUS_IS_ERR(status)) {
+                       DEBUG(2,("Failed to list %s - %s\n", 
+                                dname, nt_errstr(status)));
+                       smb2_util_close(tree, create_parm.out.file.handle);
+                       talloc_free(tmp_ctx);
+                       return -1;
                }
-               name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
-               status = smb2_util_unlink(tree, name);
-               if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
-                       /* it could be read-only */
-                       status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
+               
+               for (i=0;i<count;i++) {
+                       char *name;
+                       if (strcmp(".", list[i].name_info.name.s) == 0 ||
+                           strcmp("..", list[i].name_info.name.s) == 0) {
+                               continue;
+                       }
+                       name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
                        status = smb2_util_unlink(tree, name);
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+                               /* it could be read-only */
+                               status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
+                               status = smb2_util_unlink(tree, name);
+                       }
+                       
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+                               int ret;
+                               ret = smb2_deltree(tree, name);
+                               if (ret > 0) total_deleted += ret;
+                       }
+                       talloc_free(name);
+                       if (NT_STATUS_IS_OK(status)) {
+                               total_deleted++;
+                               did_delete = true;
+                       }
                }
-
-               if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
-                       int ret;
-                       ret = smb2_deltree(tree, name);
-                       if (ret > 0) total_deleted += ret;
-               }
-               talloc_free(name);
-               if (NT_STATUS_IS_OK(status)) {
-                       total_deleted++;
-               }
-       }
+       } while (did_delete);
 
        smb2_util_close(tree, create_parm.out.file.handle);