Print this page
6253 F_GETLK doesn't always return lock owner
The F_GETLK fcntl doesn't return the offending lock if there is a read lock
on the file, a waiting write lock, and a read lock is requested.
The write lock blocks the locking request, but without this patch isn't
returned by GETLK.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/flock.c
          +++ new/usr/src/uts/common/os/flock.c
↓ open down ↓ 2091 lines elided ↑ open up ↑
2092 2092          if (lock) {
2093 2093                  do {
2094 2094                          if (BLOCKS(lock, request)) {
2095 2095                                  blocker = lock;
2096 2096                                  break;
2097 2097                          }
2098 2098                          lock = lock->l_next;
2099 2099                  } while (lock->l_vnode == vp);
2100 2100          }
2101 2101  
     2102 +        if (blocker == NULL && request->l_flock.l_type == F_RDLCK) {
     2103 +                /*
     2104 +                 * No active lock is blocking this request, but if a read
     2105 +                 * lock is requested, it may also get blocked by a waiting
     2106 +                 * writer. So search all sleeping locks and see if there is
     2107 +                 * a writer waiting.
     2108 +                 */
     2109 +                SET_LOCK_TO_FIRST_SLEEP_VP(gp, lock, vp);
     2110 +                if (lock) {
     2111 +                        do {
     2112 +                                if (BLOCKS(lock, request)) {
     2113 +                                        blocker = lock;
     2114 +                                        break;
     2115 +                                }
     2116 +                                lock = lock->l_next;
     2117 +                        } while (lock->l_vnode == vp);
     2118 +                }
     2119 +        }
     2120 +
2102 2121          if (blocker) {
2103 2122                  report_blocker(blocker, request);
2104 2123          } else
2105 2124                  request->l_flock.l_type = F_UNLCK;
2106 2125  }
2107 2126  
2108 2127  /*
2109 2128   * Get the graph_t structure associated with a vnode.
2110 2129   * If 'initialize' is non-zero, and the graph_t structure for this vnode has
2111 2130   * not yet been initialized, then a new element is allocated and returned.
↓ open down ↓ 2159 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX