]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/safe_io.c
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/safe_io.h"
16 #include "include/compat.h"
25 ssize_t
safe_read(int fd
, void *buf
, size_t count
)
30 ssize_t r
= read(fd
, buf
, count
- cnt
);
41 buf
= (char *)buf
+ r
;
46 ssize_t
safe_read_exact(int fd
, void *buf
, size_t count
)
48 ssize_t ret
= safe_read(fd
, buf
, count
);
51 if ((size_t)ret
!= count
)
56 ssize_t
safe_write(int fd
, const void *buf
, size_t count
)
59 ssize_t r
= write(fd
, buf
, count
);
66 buf
= (char *)buf
+ r
;
71 ssize_t
safe_pread(int fd
, void *buf
, size_t count
, off_t offset
)
77 ssize_t r
= pread(fd
, b
+ cnt
, count
- cnt
, offset
+ cnt
);
93 ssize_t
safe_pread_exact(int fd
, void *buf
, size_t count
, off_t offset
)
95 ssize_t ret
= safe_pread(fd
, buf
, count
, offset
);
98 if ((size_t)ret
!= count
)
103 ssize_t
safe_pwrite(int fd
, const void *buf
, size_t count
, off_t offset
)
106 ssize_t r
= pwrite(fd
, buf
, count
, offset
);
113 buf
= (char *)buf
+ r
;
119 #ifdef CEPH_HAVE_SPLICE
120 ssize_t
safe_splice(int fd_in
, off_t
*off_in
, int fd_out
, off_t
*off_out
,
121 size_t len
, unsigned int flags
)
126 ssize_t r
= splice(fd_in
, off_in
, fd_out
, off_out
, len
- cnt
, flags
);
143 ssize_t
safe_splice_exact(int fd_in
, off_t
*off_in
, int fd_out
,
144 off_t
*off_out
, size_t len
, unsigned int flags
)
146 ssize_t ret
= safe_splice(fd_in
, off_in
, fd_out
, off_out
, len
, flags
);
149 if ((size_t)ret
!= len
)
155 int safe_write_file(const char *base
, const char *file
,
156 const char *val
, size_t vallen
,
164 // does the file already have correct content?
166 ret
= safe_read_file(base
, file
, oldval
, sizeof(oldval
));
167 if (ret
== (int)vallen
&& memcmp(oldval
, val
, vallen
) == 0)
170 snprintf(fn
, sizeof(fn
), "%s/%s", base
, file
);
171 snprintf(tmp
, sizeof(tmp
), "%s/%s.tmp", base
, file
);
172 fd
= open(tmp
, O_WRONLY
|O_CREAT
|O_TRUNC
, mode
);
177 ret
= safe_write(fd
, val
, vallen
);
179 VOID_TEMP_FAILURE_RETRY(close(fd
));
184 if (ret
< 0) ret
= -errno
;
185 VOID_TEMP_FAILURE_RETRY(close(fd
));
190 ret
= rename(tmp
, fn
);
197 fd
= open(base
, O_RDONLY
);
203 if (ret
< 0) ret
= -errno
;
204 VOID_TEMP_FAILURE_RETRY(close(fd
));
209 int safe_read_file(const char *base
, const char *file
,
210 char *val
, size_t vallen
)
215 snprintf(fn
, sizeof(fn
), "%s/%s", base
, file
);
216 fd
= open(fn
, O_RDONLY
);
220 len
= safe_read(fd
, val
, vallen
);
222 VOID_TEMP_FAILURE_RETRY(close(fd
));
225 // close sometimes returns errors, but only after write()
226 VOID_TEMP_FAILURE_RETRY(close(fd
));