r19504: - fixed a free error in file_lines_parse
authorAndrew Tridgell <tridge@samba.org>
Sat, 28 Oct 2006 06:06:15 +0000 (06:06 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:24:40 +0000 (14:24 -0500)
- added a function to test for large file support

- enable CAP_LARGE_FILES only if the test passes

- don't test at large offsets if the server doesn't set
  CAP_LARGE_FILES
(This used to be commit c5423ea22bdaa055807d4e6f7ac4be934194fe45)

source4/lib/util/util_file.c
source4/smb_server/smb/negprot.c
source4/torture/raw/read.c
source4/torture/raw/write.c

index 345171205335a70b8227f1311a88e0d27d1fc711..5d7ec40b30903e93522951be3fa650f60363245b 100644 (file)
@@ -241,6 +241,7 @@ _PUBLIC_ void *map_file(const char *fname, size_t size)
 
 /**
 parse a buffer into lines
+'p' will be freed on error, and otherwise will be made a child of the returned array
 **/
 static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
 {
@@ -259,7 +260,7 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *
                return NULL;
        }       
        
-       talloc_reference(ret, p);
+       talloc_steal(ret, p);
        
        memset(ret, 0, sizeof(ret[0])*(i+2));
        if (numlines) *numlines = i;
@@ -285,17 +286,12 @@ must be freed with talloc_free().
 _PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
 {
        char *p;
-       char **lines;
        size_t size;
 
        p = file_load(fname, &size, mem_ctx);
        if (!p) return NULL;
 
-       lines = file_lines_parse(p, size, numlines, mem_ctx);
-
-       talloc_free(p);
-
-       return lines;
+       return file_lines_parse(p, size, numlines, mem_ctx);
 }
 
 /**
@@ -306,17 +302,12 @@ the list.
 _PUBLIC_ char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx)
 {
        char *p;
-       char **lines;
        size_t size;
 
        p = fd_load(fd, &size, mem_ctx);
        if (!p) return NULL;
 
-       lines = file_lines_parse(p, size, numlines, mem_ctx);
-
-       talloc_free(p);
-
-       return lines;
+       return file_lines_parse(p, size, numlines, mem_ctx);
 }
 
 
@@ -385,3 +376,24 @@ _PUBLIC_ int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
        va_end(ap);
        return ret;
 }
+
+
+/*
+  try to determine if the filesystem supports large files
+*/
+_PUBLIC_ bool large_file_support(const char *path)
+{
+       int fd;
+       ssize_t ret;
+       char c;
+
+       fd = open(path, O_RDWR|O_CREAT, 0600);
+       unlink(path);
+       if (fd == -1) {
+               /* have to assume large files are OK */
+               return true;
+       }
+       ret = pread(fd, &c, 1, ((uint64_t)1)<<32);
+       close(fd);
+       return ret == 0;
+}
index 25684bee276210af1f315053dde51c17efee6262..4aecca53baae099c85d5bf32adf7743605d7d7b8 100644 (file)
@@ -250,6 +250,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
        time_t t = req->request_time.tv_sec;
        NTTIME nttime;
        BOOL negotiate_spnego = False;
+       char *large_test_path;
 
        unix_to_nt_time(&nttime, t);
 
@@ -277,8 +278,11 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
        if (lp_large_readwrite()) {
                capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS;
        }
-       
-       capabilities |= CAP_LARGE_FILES;
+
+       large_test_path = lock_path(req, "large_test.dat");
+       if (large_file_support(large_test_path)) {
+               capabilities |= CAP_LARGE_FILES;
+       }
 
        if (lp_readraw() && lp_writeraw()) {
                capabilities |= CAP_RAW_MODE;
index bb27ba71e585fafc5bba4fec8764d08cd9eb6124..f9c44e036e0f20f645ee0bbc965e86b7b35d3362 100644 (file)
@@ -522,6 +522,11 @@ static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_read(cli->tree, &io);
        CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
 
+       if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+               printf("skipping large file tests - CAP_LARGE_FILES not set\n");
+               goto done;
+       }
+
        printf("Trying large offset read\n");
        io.readx.in.offset = ((uint64_t)0x2) << 32;
        io.readx.in.mincnt = 10;
index 03c3897c7448efec4953417bb30ea9b376f301a8..046ca8c4f99b5eee3e6972fa07bf7ec1a50f9aa8 100644 (file)
@@ -182,6 +182,11 @@ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        printf("Setting file as sparse\n");
        status = torture_set_sparse(cli->tree, fnum);
        CHECK_STATUS(status, NT_STATUS_OK);
+
+       if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+               printf("skipping large file tests - CAP_LARGE_FILES not set\n");
+               goto done;
+       }
        
        printf("Trying 2^32 offset\n");
        setup_buffer(buf, seed, maxsize);