static bool posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) { bool ret; DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type)); ret = SMB_VFS_LOCK(fsp, op, offset, count, type); if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) { DEBUG(0,("posix_fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count)); DEBUGADD(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno))); DEBUGADD(0,("on 32 bit NFS mounted file systems.\n")); /* * If the offset is > 0x7FFFFFFF then this will cause problems on * 32 bit NFS mounted filesystems. Just ignore it. */ if (offset & ~((SMB_OFF_T)0x7fffffff)) { DEBUG(0,("Offset greater than 31 bits. Returning success.\n")); return True; } if (count & ~((SMB_OFF_T)0x7fffffff)) { /* 32 bit NFS file system, retry with smaller offset */ DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n")); errno = 0; count &= 0x7fffffff; ret = SMB_VFS_LOCK(fsp, op, offset, count, type); } } DEBUG(8,("posix_fcntl_lock: Lock call %s\n", ret ? "successful" : "failed")); return ret; }
static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { BOOL ret; int fd; int op; long offset; long count; int type; const char *typestr; if (argc != 6) { printf("Usage: lock <fd> <op> <offset> <count> <type>\n"); printf(" ops: G = F_GETLK\n"); printf(" S = F_SETLK\n"); printf(" W = F_SETLKW\n"); printf(" type: R = F_RDLCK\n"); printf(" W = F_WRLCK\n"); printf(" U = F_UNLCK\n"); return NT_STATUS_OK; } if (sscanf(argv[1], "%d", &fd) == 0) { printf("lock: error=-1 (error parsing fd)\n"); return NT_STATUS_UNSUCCESSFUL; } op = 0; switch (*argv[2]) { case 'G': op = F_GETLK; break; case 'S': op = F_SETLK; break; case 'W': op = F_SETLKW; break; default: printf("lock: error=-1 (invalid op flag!)\n"); return NT_STATUS_UNSUCCESSFUL; } if (sscanf(argv[3], "%ld", &offset) == 0) { printf("lock: error=-1 (error parsing fd)\n"); return NT_STATUS_UNSUCCESSFUL; } if (sscanf(argv[4], "%ld", &count) == 0) { printf("lock: error=-1 (error parsing fd)\n"); return NT_STATUS_UNSUCCESSFUL; } type = 0; typestr = argv[5]; while(*typestr) { switch (*typestr) { case 'R': type |= F_RDLCK; break; case 'W': type |= F_WRLCK; break; case 'U': type |= F_UNLCK; break; default: printf("lock: error=-1 (invalid type flag!)\n"); return NT_STATUS_UNSUCCESSFUL; } typestr++; } printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type); if ((ret = SMB_VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) { printf("lock: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } printf("lock: ok\n"); return NT_STATUS_OK; }