Package: smbfs
Version: 1:3.0.28a-3
Severity: normal

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

In http://bugs.debian.org/483502, i wrote:

> locking a certain range of a file with a read lock and then locking
> the same range with a write lock gives an error when a CIFS share is
> mounted with "brl".  This doesn't make much sense to me, but i'm
> willing to accept it as intended for now.

After doing more reading, it still doesn't make sense: the filesystem
is behaving with non-POSIX semantics, which causes breakage in other
packages (for example, see http://bugs.debian.org/483216).

In particular, the semantics specified by fcntl(2) for setting a lock
state:

      A single process can hold only one type of lock on a file
      region; if a new lock is applied to an already-locked region,
      then the existing lock is converted to the new lock type.

(this appears to be true for both advisory *and* mandatory locks)

However, when accessing a CIFS share mounted with with "brl" (standard
CIFS-style server-side byte-range locking), converting a read lock to
a write lock gives a "permission denied" error.

The same error does *not* occur when using the CIFS share mounted with
"nobrl", or when attempting the same series of operations against a
tmpfs (whether or not the tmpfs is mounted with -o mand).  Shouldn't
mount.cifs do its best to mimic the expected semantics of
fcntl(F_SETLK) using the underlying CIFS semantics?  If CIFS has no
explicit lock upgrade/downgrade operations, as long as the protocol is
capable of dropping a lock and acquiring a new one, these two
primitives used in sequence could be used to emulate a lock
upgrade/downgrade.

Attached is the test program that displays this behavior.  It should
fail with "write lock failed: Permission denied" when used on a file
on a CIFS mount, and it has succeeded quietly on every other
filesystem i've tried.  the latest version of the source can be found
at
http://cmrg.fifthhorseman.net/browser/trunk/test/testlocking/testlocking.c

Thanks for maintaining samba in debian!

Regards,

        --dkg

- -- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (500, 'testing'), (200, 'unstable'), (101, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 2.6.24-1-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages smbfs depends on:
ii  libc6                        2.7-10      GNU C Library: Shared libraries
ii  netbase                      4.32        Basic TCP/IP networking system
ii  samba-common                 1:3.0.28a-3 Samba common files used by both th

smbfs recommends no packages.

- -- no debconf information

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iQIVAwUBSD47NszS7ZTSFznpAQIv4A/+O3ofw/kIzXJuvtertKI2nPqcsiOT27Fl
Pf7f1Mp+qhEeVrbZ6ESZA1SSuHBeT7JKYurrsw/z7y2D6nuapqqR6DXihj9QdbIi
gZoHZhVH1tCDeuAv9pR8avV8QHXcE8BSu0vZQuaMI/zLbkxln4qbDCtOPvAmowfr
vBIKsE9Zb/hYdFCkdYP2lYGXVfTlZo26JMNKsrA+jezLk1xBPmT/UtpvD1L//19+
CNlPfTqsqAksFAqLD6TLUVgLeNv1MiMGEj9sOGiGuDXvixeCcGleemQkmbKm/ihl
viXBHYh2M9ZZtKU3I2R0tnKrwCnL1ZsU/QQb70/d3fKhJeoQrsd9jgnS0jeArLLy
RwTSWnvj1WcxId0+JT4nL6gvRNLs64fyI6QzZ/6eLHrPBQtRxEf055I2UvjO81tE
n9YA0nfIxeyeGc1+XqnE4FUmY0LEhuJT48PbsrHP5WT4XCb3mIhKg42EJ+r6WQIn
G8I0TzMZsDxXZ6vYnd4BfNKhpf0qSn2CoEcj1Jtg4lovLltc5j0VWji4iuXaLiJ3
o5rao7F0yk12iomSE2XE7gIwU7YUOHGzcqx011cDNmv/z2Vdr8tFCB8Svh7Y6VMA
0LcDH8LLVGSlXneP5frzUimBS1A6ogu8ocYxhIp4ww60Lqq1TOOIebj2m/znaaj4
CWuXI6GnK+w=
=y3y4
-----END PGP SIGNATURE-----
/* grep open(2) for O_LARGEFILE to explain this: */
#define _FILE_OFFSET_BITS 64

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

/* 
   Author: Daniel Kahn Gillmor <[EMAIL PROTECTED]>
   Date: 2008-05-28

   This is a demonstration program for testing
   http://bugs.debian.org/483216
 */

int main(int argc, char* argv[]) {
  struct flock flock;
  int fd;

  flock.l_whence=SEEK_SET;

  /* open file, get file descriptor */
  fd = open(argv[1], O_RDWR|O_CREAT, 0644);

  fcntl(fd, F_SETFD, FD_CLOEXEC | fcntl(fd, F_GETFD));

  /* get read lock: */
  flock.l_type=F_RDLCK;
  flock.l_start=0;
  flock.l_len = 1;
  if (0 != fcntl(fd, F_SETLK64, &flock)) {
    perror("read lock failed");
    return 1;
  }

  /* get write lock for same range: */
  flock.l_type=F_WRLCK;
  if (0 != fcntl(fd, F_SETLK64, &flock)) {
    /* fails here when used on CIFS share mounted without nobrl option */
    perror("write lock failed");
    return 1;
  }
    
  return 0;
}

Reply via email to