Cloud-based services are emerging as an economical and convenient alternative for clients who don't want to acquire, maintain and operate their own IT equipment. Instead, customers purchase virtual machines (VMs) with certain service level objectives (SLOs) to obtain computational resources. Existing algorithms for memory and CPU allocation are inadequate for I/O allocation, especially in clustered storage infrastructures where storage is distributed across multiple storage nodes. This paper focuses on: 1) dynamic SLO decomposition so that VMs receive proper I/O service in each distributed storage node, and 2) efficient and robust local I/O scheduling strategy. To address these issues, we present an adaptive I/O resource scheduling algorithm (called PC) for utility optimization that at runtime adjusts local SLOs. The local SLOs are generated for each VM at each storage node based on access patterns. We also adopt dual clocks to allow automatic switching between two scheduling strategies. When system capacity is sufficient, we interweave requests in an earliest deadline first (EDF) manner. Otherwise resources are allocated proportionately to their normalized revenues. The results of our experiments suggest that the algorithm is adaptive to various access patterns without significant manual pre-settings while maximizing profits.