Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cc21dff authored by Hyeeun Jun's avatar Hyeeun Jun Committed by Omar Eissa
Browse files

Prevent app fuse from indefinitely trying if it gets ENOBUFS

When there is not enough memory to allocate the appfuse socket,
ENOBUFS error could occur repeatly, and the retry will not be ended.
Limit the retry count to prevent infinite repetition.

Limited this to take only 5 seconds which is still quite high but still
better than running indefinitely. We can reduce this further later on.

Test: Manual
Bug: 312503249
Bug: 369519866
Change-Id: I928b7b5e6d0a53831c2b35d48aeb9440e8f6564a
parent 88d79e02
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ namespace fuse {
namespace {

constexpr useconds_t kRetrySleepForWriting = 1000;  // 1 ms
// This makes the total wait time to allocate a buffer 5 seconds
const int kNumberOfRetriesForWriting = 5000;

template <typename T>
bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) {
@@ -92,6 +94,7 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co

    const char* const buf = reinterpret_cast<const char*>(self);
    const auto& header = static_cast<const T*>(self)->header;
    int retry = kNumberOfRetriesForWriting;

    while (true) {
        int result;
@@ -110,8 +113,14 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co
                case ENOBUFS:
                    // When returning ENOBUFS, epoll still reports the FD is writable. Just usleep
                    // and retry again.
                    if (retry > 0) {
                        usleep(kRetrySleepForWriting);
                        retry--;
                        continue;
                    } else {
                        LOG(ERROR) << "Failed to write a FUSE message: ENOBUFS retries are failed";
                        return ResultOrAgain::kFailure;
                    }
                case EAGAIN:
                    return ResultOrAgain::kAgain;
                default: