File tree Expand file tree Collapse file tree 4 files changed +40
-0
lines changed Expand file tree Collapse file tree 4 files changed +40
-0
lines changed Original file line number Diff line number Diff line change @@ -314,6 +314,30 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
314314 unsigned int tail = pipe -> tail ;
315315 unsigned int mask = pipe -> ring_size - 1 ;
316316
317+ #ifdef CONFIG_WATCH_QUEUE
318+ if (pipe -> note_loss ) {
319+ struct watch_notification n ;
320+
321+ if (total_len < 8 ) {
322+ if (ret == 0 )
323+ ret = - ENOBUFS ;
324+ break ;
325+ }
326+
327+ n .type = WATCH_TYPE_META ;
328+ n .subtype = WATCH_META_LOSS_NOTIFICATION ;
329+ n .info = watch_sizeof (n );
330+ if (copy_to_iter (& n , sizeof (n ), to ) != sizeof (n )) {
331+ if (ret == 0 )
332+ ret = - EFAULT ;
333+ break ;
334+ }
335+ ret += sizeof (n );
336+ total_len -= sizeof (n );
337+ pipe -> note_loss = false;
338+ }
339+ #endif
340+
317341 if (!pipe_empty (head , tail )) {
318342 struct pipe_buffer * buf = & pipe -> bufs [tail & mask ];
319343 size_t chars = buf -> len ;
@@ -355,6 +379,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
355379 if (!buf -> len ) {
356380 pipe_buf_release (pipe , buf );
357381 spin_lock_irq (& pipe -> rd_wait .lock );
382+ #ifdef CONFIG_WATCH_QUEUE
383+ if (buf -> flags & PIPE_BUF_FLAG_LOSS )
384+ pipe -> note_loss = true;
385+ #endif
358386 tail ++ ;
359387 pipe -> tail = tail ;
360388 spin_unlock_irq (& pipe -> rd_wait .lock );
Original file line number Diff line number Diff line change 99#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
1010#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */
1111#define PIPE_BUF_FLAG_WHOLE 0x10 /* read() must return entire buffer or error */
12+ #ifdef CONFIG_WATCH_QUEUE
13+ #define PIPE_BUF_FLAG_LOSS 0x20 /* Message loss happened after this buffer */
14+ #endif
1215
1316/**
1417 * struct pipe_buffer - a linux kernel pipe buffer
@@ -34,6 +37,7 @@ struct pipe_buffer {
3437 * @wr_wait: writer wait point in case of full pipe
3538 * @head: The point of buffer production
3639 * @tail: The point of buffer consumption
40+ * @note_loss: The next read() should insert a data-lost message
3741 * @max_usage: The maximum number of slots that may be used in the ring
3842 * @ring_size: total number of buffers (should be a power of 2)
3943 * @nr_accounted: The amount this pipe accounts for in user->pipe_bufs
@@ -56,6 +60,9 @@ struct pipe_inode_info {
5660 unsigned int tail ;
5761 unsigned int max_usage ;
5862 unsigned int ring_size ;
63+ #ifdef CONFIG_WATCH_QUEUE
64+ bool note_loss ;
65+ #endif
5966 unsigned int nr_accounted ;
6067 unsigned int readers ;
6168 unsigned int writers ;
Original file line number Diff line number Diff line change @@ -132,6 +132,8 @@ static bool post_one_notification(struct watch_queue *wqueue,
132132 return done ;
133133
134134lost :
135+ buf = & pipe -> bufs [(head - 1 ) & mask ];
136+ buf -> flags |= PIPE_BUF_FLAG_LOSS ;
135137 goto out ;
136138}
137139
Original file line number Diff line number Diff line change @@ -120,6 +120,9 @@ static void consumer(int fd)
120120 (n .n .info & WATCH_INFO_ID ) >>
121121 WATCH_INFO_ID__SHIFT );
122122 break ;
123+ case WATCH_META_LOSS_NOTIFICATION :
124+ printf ("-- LOSS --\n" );
125+ break ;
123126 default :
124127 printf ("other meta record\n" );
125128 break ;
You can’t perform that action at this time.
0 commit comments