00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define DBGC_CLASS DBGC_LOCKING
00022 #include "includes.h"
00023
00024 #if HAVE_KERNEL_OPLOCKS_IRIX
00025
00026 static int oplock_pipe_write = -1;
00027 static int oplock_pipe_read = -1;
00028
00029
00030
00031
00032
00033 static BOOL irix_oplocks_available(void)
00034 {
00035 int fd;
00036 int pfd[2];
00037 pstring tmpname;
00038
00039 set_effective_capability(KERNEL_OPLOCK_CAPABILITY);
00040
00041 slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(),
00042 (int)sys_getpid());
00043
00044 if(pipe(pfd) != 0) {
00045 DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error "
00046 "was %s\n",
00047 strerror(errno) ));
00048 return False;
00049 }
00050
00051 if((fd = sys_open(tmpname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600)) < 0) {
00052 DEBUG(0,("check_kernel_oplocks: Unable to open temp test file "
00053 "%s. Error was %s\n",
00054 tmpname, strerror(errno) ));
00055 unlink( tmpname );
00056 close(pfd[0]);
00057 close(pfd[1]);
00058 return False;
00059 }
00060
00061 unlink(tmpname);
00062
00063 if(sys_fcntl_long(fd, F_OPLKREG, pfd[1]) == -1) {
00064 DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not "
00065 "available on this machine. Disabling kernel oplock "
00066 "support.\n" ));
00067 close(pfd[0]);
00068 close(pfd[1]);
00069 close(fd);
00070 return False;
00071 }
00072
00073 if(sys_fcntl_long(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
00074 DEBUG(0,("check_kernel_oplocks: Error when removing kernel "
00075 "oplock. Error was %s. Disabling kernel oplock "
00076 "support.\n", strerror(errno) ));
00077 close(pfd[0]);
00078 close(pfd[1]);
00079 close(fd);
00080 return False;
00081 }
00082
00083 close(pfd[0]);
00084 close(pfd[1]);
00085 close(fd);
00086
00087 return True;
00088 }
00089
00090
00091
00092
00093
00094
00095 static files_struct *irix_oplock_receive_message(fd_set *fds)
00096 {
00097 extern int smb_read_error;
00098 oplock_stat_t os;
00099 char dummy;
00100 files_struct *fsp;
00101
00102
00103 FD_CLR(oplock_pipe_read, fds);
00104
00105
00106
00107
00108
00109
00110 if(read(oplock_pipe_read, &dummy, 1) != 1) {
00111 DEBUG(0,("irix_oplock_receive_message: read of kernel "
00112 "notification failed. Error was %s.\n",
00113 strerror(errno) ));
00114 smb_read_error = READ_ERROR;
00115 return NULL;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 if(sys_fcntl_ptr(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
00125 DEBUG(0,("irix_oplock_receive_message: fcntl of kernel "
00126 "notification failed. Error was %s.\n",
00127 strerror(errno) ));
00128 if(errno == EAGAIN) {
00129
00130
00131
00132 return NULL;
00133 }
00134 smb_read_error = READ_ERROR;
00135 return NULL;
00136 }
00137
00138
00139
00140
00141
00142
00143 if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev,
00144 (SMB_INO_T)os.os_ino)) == NULL) {
00145 DEBUG(0,("irix_oplock_receive_message: unable to find open "
00146 "file with dev = %x, inode = %.0f\n",
00147 (unsigned int)os.os_dev, (double)os.os_ino ));
00148 return NULL;
00149 }
00150
00151 DEBUG(5,("irix_oplock_receive_message: kernel oplock break request "
00152 "received for dev = %x, inode = %.0f\n, file_id = %ul",
00153 (unsigned int)fsp->dev, (double)fsp->inode,
00154 fsp->fh->file_id ));
00155
00156 return fsp;
00157 }
00158
00159
00160
00161
00162
00163 static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type)
00164 {
00165 if (sys_fcntl_long(fsp->fh->fd, F_OPLKREG, oplock_pipe_write) == -1) {
00166 if(errno != EAGAIN) {
00167 DEBUG(0,("irix_set_kernel_oplock: Unable to get "
00168 "kernel oplock on file %s, dev = %x, inode "
00169 "= %.0f, file_id = %ul. Error was %s\n",
00170 fsp->fsp_name, (unsigned int)fsp->dev,
00171 (double)fsp->inode, fsp->fh->file_id,
00172 strerror(errno) ));
00173 } else {
00174 DEBUG(5,("irix_set_kernel_oplock: Refused oplock on "
00175 "file %s, fd = %d, dev = %x, inode = %.0f, "
00176 "file_id = %ul. Another process had the file "
00177 "open.\n",
00178 fsp->fsp_name, fsp->fh->fd,
00179 (unsigned int)fsp->dev, (double)fsp->inode,
00180 fsp->fh->file_id ));
00181 }
00182 return False;
00183 }
00184
00185 DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, dev "
00186 "= %x, inode = %.0f, file_id = %ul\n",
00187 fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
00188 fsp->fh->file_id));
00189
00190 return True;
00191 }
00192
00193
00194
00195
00196
00197 static void irix_release_kernel_oplock(files_struct *fsp)
00198 {
00199 if (DEBUGLVL(10)) {
00200
00201
00202
00203
00204 int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1);
00205 dbgtext("irix_release_kernel_oplock: file %s, dev = %x, "
00206 "inode = %.0f file_id = %ul, has kernel oplock state "
00207 "of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
00208 (double)fsp->inode, fsp->fh->file_id, state );
00209 }
00210
00211
00212
00213
00214 if(sys_fcntl_long(fsp->fh->fd, F_OPLKACK, OP_REVOKE) < 0) {
00215 if( DEBUGLVL( 0 )) {
00216 dbgtext("irix_release_kernel_oplock: Error when "
00217 "removing kernel oplock on file " );
00218 dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. "
00219 "Error was %s\n",
00220 fsp->fsp_name, (unsigned int)fsp->dev,
00221 (double)fsp->inode, fsp->fh->file_id,
00222 strerror(errno) );
00223 }
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232 static BOOL irix_oplock_msg_waiting(fd_set *fds)
00233 {
00234 int selrtn;
00235 fd_set myfds;
00236 struct timeval to;
00237
00238 if (oplock_pipe_read == -1)
00239 return False;
00240
00241 if (fds) {
00242 return FD_ISSET(oplock_pipe_read, fds);
00243 }
00244
00245
00246
00247
00248
00249 FD_ZERO(&myfds);
00250 FD_SET(oplock_pipe_read, &myfds);
00251
00252 to = timeval_set(0, 0);
00253 selrtn = sys_select_intr(oplock_pipe_read+1,&myfds,NULL,NULL,&to);
00254 return (selrtn == 1) ? True : False;
00255 }
00256
00257
00258
00259
00260
00261 struct kernel_oplocks *irix_init_kernel_oplocks(void)
00262 {
00263 int pfd[2];
00264 static struct kernel_oplocks koplocks;
00265
00266 if (!irix_oplocks_available())
00267 return NULL;
00268
00269 if(pipe(pfd) != 0) {
00270 DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. "
00271 "Error was %s\n", strerror(errno) ));
00272 return False;
00273 }
00274
00275 oplock_pipe_read = pfd[0];
00276 oplock_pipe_write = pfd[1];
00277
00278 koplocks.receive_message = irix_oplock_receive_message;
00279 koplocks.set_oplock = irix_set_kernel_oplock;
00280 koplocks.release_oplock = irix_release_kernel_oplock;
00281 koplocks.msg_waiting = irix_oplock_msg_waiting;
00282 koplocks.notification_fd = oplock_pipe_read;
00283
00284 return &koplocks;
00285 }
00286 #else
00287 void oplock_irix_dummy(void);
00288 void oplock_irix_dummy(void) {}
00289 #endif