Пример #1
0
/*
 * First creates the parent directories of the file using
 * fileset_mkdir(). Then Optionally sets the O_DSYNC flag
 * and opens the file with open64(). It unlocks the fileset
 * entry lock, sets the DIRECTIO_ON or DIRECTIO_OFF flags
 * as requested, and returns the file descriptor integer
 * for the opened file.
 */
int
fileset_openfile(fileset_t *fileset,
    filesetentry_t *entry, int flag, int mode, int attrs)
{
	char path[MAXPATHLEN];
	char dir[MAXPATHLEN];
	char *pathtmp;
	struct stat64 sb;
	int fd;
	int open_attrs = 0;

	*path = 0;
	(void) strcpy(path, *fileset->fs_path);
	(void) strcat(path, "/");
	(void) strcat(path, fileset->fs_name);
	pathtmp = fileset_resolvepath(entry);
	(void) strcat(path, pathtmp);
	(void) strcpy(dir, path);
	free(pathtmp);
	(void) trunc_dirname(dir);

	/* If we are going to create a file, create the parent dirs */
	if ((flag & O_CREAT) && (stat64(dir, &sb) != 0)) {
		if (fileset_mkdir(dir, 0755) == -1)
			return (-1);
	}

	if (flag & O_CREAT)
		entry->fse_flags |= FSE_EXISTS;

	if (attrs & FLOW_ATTR_DSYNC) {
#ifdef sun
		open_attrs |= O_DSYNC;
#else
		open_attrs |= O_FSYNC;
#endif
	}

	if ((fd = open64(path, flag | open_attrs, mode)) < 0) {
		filebench_log(LOG_ERROR,
		    "Failed to open file %s: %s",
		    path, strerror(errno));
		(void) ipc_mutex_unlock(&entry->fse_lock);
		return (-1);
	}
	(void) ipc_mutex_unlock(&entry->fse_lock);

#ifdef sun
	if (attrs & FLOW_ATTR_DIRECTIO)
		(void) directio(fd, DIRECTIO_ON);
	else
		(void) directio(fd, DIRECTIO_OFF);
#endif

	return (fd);
}
Пример #2
0
int
benchmark_initbatch(void *tsd)
{
	tsd_t			*ts = (tsd_t *)tsd;
	int			i;

	if (ts->ts_buf == NULL) {
		ts->ts_buf = malloc(opts);
		ts->ts_fd = open(optf, O_WRONLY);

#ifdef __sun
		if (optd)
			(void) directio(ts->ts_fd, DIRECTIO_ON);
#endif
		/*
		 * bring buf into cache if specified.
		 */

		if (optc)
			for (i = 0; i < opts; i++)
				ts->ts_buf[i] = 0;
	}

	(void) lseek(ts->ts_fd, 0, SEEK_SET);

	return (0);
}
Пример #3
0
/*
 * call-seq:
 *    IO#directio=(advice)
 *
 * Sets the advice for the current file descriptor using directio().  Valid
 * values are IO::DIRECTIO_ON and IO::DIRECTIO_OFF. See the directio(3c) man
 * page for more information.
 *
 * All file descriptors start at DIRECTIO_OFF, unless your filesystem has
 * been mounted using 'forcedirectio' (and supports that option).
 */
static VALUE io_set_directio(VALUE self, VALUE v_advice){
   int fd;
   int advice = NUM2INT(v_advice);

   /* Only two possible valid values */
   if( (advice != DIRECTIO_OFF) && (advice != DIRECTIO_ON) )
      rb_raise(rb_eStandardError, "Invalid value passed to IO#directio=");

   /* Retrieve the current file descriptor in order to pass it to directio() */
   fd = NUM2INT(rb_funcall(self, rb_intern("fileno"), 0, 0));

#if defined(HAVE_DIRECTIO)
   if(directio(fd, advice) < 0)
      rb_raise(rb_eStandardError, "The directio() call failed");

   if(advice == DIRECTIO_ON)
      rb_iv_set(self, "@directio", Qtrue);
   else
      rb_iv_set(self, "@directio", Qfalse);
#else
   {
#if defined(O_DIRECT)
      int flags = fcntl(fd, F_GETFL);

      if(flags < 0)
         rb_sys_fail("fcntl");

      if(advice == DIRECTIO_OFF){
         if(flags & O_DIRECT){
            if(fcntl(fd, F_SETFL, flags & ~O_DIRECT) < 0)
               rb_sys_fail("fcntl");
         }
      } else { /* DIRECTIO_ON */
         if(!(flags & O_DIRECT)){
            if(fcntl(fd, F_SETFL, flags | O_DIRECT) < 0)
               rb_sys_fail("fcntl");
         }
      }
#elif defined(F_NOCACHE)
      if(advice == DIRECTIO_OFF){
         if(fcntl(fd, F_NOCACHE, 0) < 0)
            rb_sys_fail("fcntl");
         rb_iv_set(self, "@directio", Qfalse);
      } else { /* DIRECTIO_ON*/
         if(fcntl(fd, F_NOCACHE, 1) < 0)
            rb_sys_fail("fcntl");
         rb_iv_set(self, "@directio", Qtrue);
      }
#endif
   }
#endif

   return self;
}
Пример #4
0
int main()
{
  int i,read_count, fd;
  char * data = (char *) malloc (read_size);
  fd = open("/adsl-pool2/myfs/a", O_RDWR); 
  directio(fd, DIRECTIO_ON); 
  if (fd == -1)
    printf ("Open failed with error no %d", errno); 
  read_count = read(fd, data, read_size); 
  if (read_count > 0)
  { 
     printf ("Successfuly read %d count(s).\n", read_count);
     data[read_count] = 0; 
     printf ("File contents are : - \n");
     printf("%s", data);
  }
  else
    printf ("Read failed or something bad happened. btw, errno is %d.\n", errno);
  close (fd);
}
Пример #5
0
bbcp_File *bbcp_FS_Unix::Open(const char *fn, int opts, int mode, const char *fa)
{
    static const int rwxMask = S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO;
    int FD;
    bbcp_IO *iob;

// Check for direct I/O
//
#ifdef O_DIRECT
   if (dIO) opts |= O_DIRECT;
#endif

// Open the file
//
   mode &= rwxMask;
   if ((FD = (mode ? open(fn, opts, mode) : open(fn, opts))) < 0) 
      return (bbcp_File *)0;

// Advise about file access in Linux
//
#ifdef LINUX
   posix_fadvise(FD,0,0,POSIX_FADV_SEQUENTIAL|POSIX_FADV_NOREUSE);
#endif

// Do direct I/O for Solaris
//
#ifdef SUN
   if (dIO && directio(FD, DIRECTIO_ON))
      {DEBUG(strerror(errno) <<" requesting direct i/o for " <<fn); dIO = 0;}
#endif

// Allocate a file object and return that
//
   iob =  new bbcp_IO(FD);
   return new bbcp_File(fn, iob, (bbcp_FileSystem *)this, (dIO ? secSize : 0));
}
Пример #6
0
/* Open a VMFS volume */
vmfs_volume_t *vmfs_vol_open(const char *filename,vmfs_flags_t flags)
{
   vmfs_volume_t *vol;
   struct stat st;
   int file_flags;

   if (!(vol = calloc(1,sizeof(*vol))))
      return NULL;

   if (!(vol->device = strdup(filename)))
      goto err_filename;

   file_flags = (flags.read_write) ? O_RDWR : O_RDONLY;

   if ((vol->fd = open(vol->device,file_flags)) < 0) {
      perror("open");
      goto err_open;
   }

   vol->flags = flags;
   fstat(vol->fd,&st);
   vol->is_blkdev = S_ISBLK(st.st_mode);
#if defined(O_DIRECT) || defined(DIRECTIO_ON)
   if (vol->is_blkdev)
#ifdef O_DIRECT
      fcntl(vol->fd, F_SETFL, O_DIRECT);
#else
#ifdef DIRECTIO_ON
      directio(vol->fd, DIRECTIO_ON);
#endif
#endif
#endif

   vol->vmfs_base = VMFS_VOLINFO_BASE;

   /* Read volume information */
   do {
      DECL_ALIGNED_BUFFER(buf,512);
      uint16_t magic;
      /* Look for the MBR magic number */
      m_pread(vol->fd,buf,buf_len,0);
      magic = read_le16(buf, 510);
      if (magic == 0xaa55) {
         /* Scan partition table */
         int off;
         for (off = 446; off < 510; off += 16) {
            if (buf[off + 4] == 0xfb) {
                vol->vmfs_base += (off_t) read_le32(buf, off + 8) * 512;
                break;
            }
         }
      }
   } while(0);

   if (vmfs_volinfo_read(vol) == -1)
      goto err_open;

   /* We support only VMFS3 and VMFS5*/
   if ((vol->vol_info.version != 3) && (vol->vol_info.version != 5)) {
      fprintf(stderr,"VMFS: Unsupported version %u\n",vol->vol_info.version);
      goto err_open;
   }

   if ((vol->vol_info.version == 5) && flags.read_write) {
      fprintf(stderr, "VMFS: Can't open VMFS read/write\n");
      goto err_open;
   }

   if (vol->is_blkdev && (scsi_get_lun(vol->fd) != vol->vol_info.lun))
      fprintf(stderr,"VMFS: Warning: Lun ID mismatch on %s\n", vol->device);

   vmfs_vol_check_reservation(vol);

   if (vol->flags.debug_level > 0) {
      printf("VMFS: volume opened successfully\n");
   }

   vol->dev.read = vmfs_vol_read;
   if (vol->flags.read_write)
      vol->dev.write = vmfs_vol_write;
   vol->dev.close = vmfs_vol_close;
   vol->dev.uuid = &vol->vol_info.lvm_uuid;

   return vol;

 err_open:
   free(vol->device);
 err_filename:
   free(vol);
   return NULL;
}
Пример #7
0
	bool file::open(std::string const& path, open_mode_t mode, error_code& ec)
	{
		close();
		native_path_string file_path = convert_to_native_path_string(path);

#ifdef TORRENT_WINDOWS

		struct win_open_mode_t
		{
			DWORD rw_mode;
			DWORD create_mode;
		};

		static std::array<win_open_mode_t, 3> const mode_array{
		{
			// read_only
			{GENERIC_READ, OPEN_EXISTING},
			// write_only
			{GENERIC_WRITE, OPEN_ALWAYS},
			// read_write
			{GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS},
		}};

		static std::array<DWORD, 4> const attrib_array{
		{
			FILE_ATTRIBUTE_NORMAL, // no attrib
			FILE_ATTRIBUTE_HIDDEN, // hidden
			FILE_ATTRIBUTE_NORMAL, // executable
			FILE_ATTRIBUTE_HIDDEN, // hidden + executable
		}};

		TORRENT_ASSERT(static_cast<std::uint32_t>(mode & open_mode::rw_mask) < mode_array.size());
		win_open_mode_t const& m = mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)];
		DWORD a = attrib_array[static_cast<std::uint32_t>(mode & open_mode::attribute_mask) >> 12];

		// one might think it's a good idea to pass in FILE_FLAG_RANDOM_ACCESS. It
		// turns out that it isn't. That flag will break your operating system:
		// http://support.microsoft.com/kb/2549369

		DWORD const flags = ((mode & open_mode::random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN)
			| (a ? a : FILE_ATTRIBUTE_NORMAL)
			| FILE_FLAG_OVERLAPPED
			| ((mode & open_mode::no_cache) ? FILE_FLAG_WRITE_THROUGH : 0);

		handle_type handle = CreateFileW(file_path.c_str(), m.rw_mode
			, FILE_SHARE_READ | FILE_SHARE_WRITE
			, 0, m.create_mode, flags, 0);

		if (handle == INVALID_HANDLE_VALUE)
		{
			ec.assign(GetLastError(), system_category());
			TORRENT_ASSERT(ec);
			return false;
		}

		m_file_handle = handle;

		// try to make the file sparse if supported
		// only set this flag if the file is opened for writing
		if ((mode & open_mode::sparse)
			&& (mode & open_mode::rw_mask) != open_mode::read_only)
		{
			DWORD temp;
			overlapped_t ol;
			BOOL ret = ::DeviceIoControl(native_handle(), FSCTL_SET_SPARSE, 0, 0
				, 0, 0, &temp, &ol.ol);
			error_code error;
			if (ret == FALSE && GetLastError() == ERROR_IO_PENDING)
				ol.wait(native_handle(), error);
		}
#else // TORRENT_WINDOWS

		// rely on default umask to filter x and w permissions
		// for group and others
		int permissions = S_IRUSR | S_IWUSR
			| S_IRGRP | S_IWGRP
			| S_IROTH | S_IWOTH;

		if ((mode & open_mode::attribute_executable))
			permissions |= S_IXGRP | S_IXOTH | S_IXUSR;
#ifdef O_BINARY
		static const int mode_array[] = {O_RDONLY | O_BINARY, O_WRONLY | O_CREAT | O_BINARY, O_RDWR | O_CREAT | O_BINARY};
#else
		static const int mode_array[] = {O_RDONLY, O_WRONLY | O_CREAT, O_RDWR | O_CREAT};
#endif

		int open_mode = 0
#ifdef O_NOATIME
			| ((mode & open_mode::no_atime) ? O_NOATIME : 0)
#endif
#ifdef O_SYNC
			| ((mode & open_mode::no_cache) ? O_SYNC : 0)
#endif
			;

		handle_type handle = ::open(file_path.c_str()
			, mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)] | open_mode
			, permissions);

#ifdef O_NOATIME
		// O_NOATIME is not allowed for files we don't own
		// so, if we get EPERM when we try to open with it
		// try again without O_NOATIME
		if (handle == -1 && (mode & open_mode::no_atime) && errno == EPERM)
		{
			mode &= ~open_mode::no_atime;
			open_mode &= ~O_NOATIME;
			handle = ::open(file_path.c_str()
				, mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)] | open_mode
				, permissions);
		}
#endif
		if (handle == -1)
		{
			ec.assign(errno, system_category());
			TORRENT_ASSERT(ec);
			return false;
		}

		m_file_handle = handle;

#ifdef DIRECTIO_ON
		// for solaris
		if ((mode & open_mode::no_cache))
		{
			int yes = 1;
			directio(native_handle(), DIRECTIO_ON);
		}
#endif

#ifdef F_NOCACHE
		// for BSD/Mac
		if ((mode & open_mode::no_cache))
		{
			int yes = 1;
			::fcntl(native_handle(), F_NOCACHE, &yes);

#ifdef F_NODIRECT
			// it's OK to temporarily cache written pages
			::fcntl(native_handle(), F_NODIRECT, &yes);
#endif
		}
#endif

#ifdef POSIX_FADV_RANDOM
		if ((mode & open_mode::random_access))
		{
			// disable read-ahead
			// NOTE: in android this function was introduced in API 21,
			// but the constant POSIX_FADV_RANDOM is there for lower
			// API levels, just don't add :: to allow a macro workaround
			posix_fadvise(native_handle(), 0, 0, POSIX_FADV_RANDOM);
		}
#endif

#endif
		m_open_mode = mode;

		TORRENT_ASSERT(is_open());
		return true;
	}