Messages in this thread Patches in this message | | | Subject | knfs quota fix, and some locking ramblings. | Date | Sat, 10 Apr 1999 04:43:17 +0200 | From | Anders Hammarquist <> |
| |
First, as maintainer of the Debian knfs tools, I got a report that chown() from an nfs client didn't properly update quotas on the server.
A quick look in nfsd/vfs.c revealed that setattr didn't do DQUOT_TRANSFER() if the owner changed. The first patch fixes that. Note! I haven't been able to test it since I couldn't get quotas working (alpha problem perhaps?), but it seems simple enough. The patch is relative 2.2.5 + patches in knfsd-1.2.2 tarball. (Scott, can you try it please?)
Then, I was also told that files marked for mandatory locking were not openable via NFS (even if they weren't regular files). The first fix was pretty obvious, make sure the file is a regular file before deciding it is marked for mandatory locking. I also noted that the nfs server always clears the setgid bit of a file when it is written to (this should not occur if the file is marked for mandatory locking).
The question is, should they be openable via NFS? And if so, under what circumstances? The current NFS client refuses to lock files marked for mandatory locking (is there a reason other than that locking doesn't work well over NFS for this?). I tentatively changed things to allow opens unless the file is already locked on the server... This patch is relative 2.2.5 + knfsd-1.2.2 + quota patch.
Also, in playing around with the locking I noted that locks on the server are independent from locks on the clients. That is, if one NFS client locks a file, the lock is seen by other NFS clients. However, locks on the server are not seen on the clients, and the server doesn't see client locks, so trying to lock a file on a client and the server, both obtain a lock! I haven't been able to figure out why this is happening though...
Regards, /Anders Index: linux/fs/nfsd/vfs.c =================================================================== RCS file: /archive/CVS/linux/fs/nfsd/vfs.c,v retrieving revision 1.8 diff -u -r1.8 vfs.c --- vfs.c 1999/04/05 23:41:18 1.8 +++ vfs.c 1999/04/10 01:50:33 @@ -47,7 +47,7 @@ /* Hack until we have a macro check for mandatory locks. */ #ifndef IS_ISMNDLK -#define IS_ISMNDLK(i) (((i)->i_mode & (S_ISGID|S_IXGRP)) == S_ISGID) +#define IS_ISMNDLK(i) (((i)->i_mode & (S_ISGID|S_IXGRP|S_IFMT)) == S_IFREG|S_ISGID) #endif /* Check for dir entries '.' and '..' */ @@ -331,7 +334,7 @@ * with mandatory locking enabled */ err = nfserr_perm; - if (IS_APPEND(inode) || IS_ISMNDLK(inode)) + if (IS_APPEND(inode) || locks_verify_locked(inode)) goto out; if (!inode->i_op || !inode->i_op->default_file_ops) goto out; @@ -550,13 +553,15 @@ #endif set_fs(oldfs); - /* clear setuid/setgid flag after write */ + /* clear setuid/setgid flag after write unless mandatory lock */ if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) { struct iattr ia; kernel_cap_t saved_cap = 0; ia.ia_valid = ATTR_MODE; - ia.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID); + ia.ia_mode = inode->i_mode & ~S_ISUID; + if (inode->i_mode & S_IXGRP) + ia.ia_mode = inode->i_mode & ~S_ISGID; if (current->fsuid != 0) { saved_cap = current->cap_effective; cap_clear(current->cap_effective);Index: linux/fs/nfsd/vfs.c =================================================================== RCS file: /archive/CVS/linux/fs/nfsd/vfs.c,v retrieving revision 1.8 diff -u -r1.8 vfs.c --- vfs.c 1999/04/05 23:41:18 1.8 +++ vfs.c 1999/04/10 01:50:33 @@ -289,7 +289,10 @@ saved_cap = current->cap_effective; cap_clear(current->cap_effective); } - err = notify_change(dentry, iap); + if (iap->ia_valid & (ATTR_UID|ATTR_GID)) + err = DQUOT_TRANSFER(dentry, iap); + else + err = notify_change(dentry, iap); if (current->fsuid != 0) current->cap_effective = saved_cap; if (err) -- Of course I'm crazy, but that doesn't mean I'm wrong. Anders Hammarquist | iko@{cd.chalmers,iko.pp}.se Physics Student, root, Debian Maintainer | Tel: +46.31.47 69 27 Jag ska b|rja plugga i l{svecka 1... | Cel: +46.707.27 86 87
| |