Skip to contentSkip to conversation

Question: When NFS client check dir's permission, it does not check the cache data

PATCH Wei Yongjun 3 participants 10 messages Jun 25, 2007 – Jul 26, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hello, everyone
When I test NFS client, I found a poblem that, if a dir we do not have
permission to write, it will let the server to check permissions when we perform the write op.
This is comment by source code:
* Optimize away all write operations, since the server
* will check permissions when we perform the op.
In my test, the process is like following:
#touch dir/file
NFS Server NFS Client

                       <----------      lookup (dir)
lookup ok      ------------->
                       <----------      access (dir)   (*1)
access(read only)   -----------> 
                       <----------      lookup (file)
lookup(NOENT)     ------------->
                       <----------      create (file)  (*2)

create(NOPERM) ------------->

(*1)
First to check the permissions of that dir ,and will be add to cache data. (*2)
Since the Client had known the permission of the dir, why no used it? Does this effect to NFS client's performance?
Maybe we can check the cache first, if it not exists, then let the server to check permissions when we perform the write op.
Is this better? Maybe code looks like following(not an useable patch):

nfs/dir.c renamed from nfs/dir.c.orig +0 -0
@@ -1936,6 +1936,14 @@ static int nfs_do_access(struct inode *i
        ...
	status = nfs_access_get_cached(inode, cred, &cache);

if (status == 0)
goto out;

+ /*
+ * Optimize away all write operations, since the server
+ * will check permissions when we perform the op.
+ */
+ if(((inode->i_mode & S_IFMT) == S_IFDIR)
+ && (mask & MAY_WRITE) && !(mask & MAY_READ))
+ return 0;
+
/* Be clever: ask server to check for all possible rights */ cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ; cache.cred = cred;
@@ -1973,13 +1981,6 @@ int nfs_permission(struct inode *inode,
&& (nd->flags & LOOKUP_OPEN))
goto out;
break;
- case S_IFDIR:
- /*
- * Optimize away all write operations, since the server
- * will check permissions when we perform the op.
- */
- if ((mask & MAY_WRITE) && !(mask & MAY_READ))
- goto out;
}

force_lookup:

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#1 lore raw

Or for that matter, just drop the 'access' and the second 'lookup' and just try the 'create'.

-----Original Message-----
From: Wei Yongjun [mailto:[email protected]]
Sent: Monday, June 25, 2007 1:52 AM
To: [email protected]
Subject: [NFS] Question: When NFS client check dir's permission, it does not check the cache data

Hello, everyone
When I test NFS client, I found a poblem that, if a dir we do not have
permission to write, it will let the server to check permissions when we perform the write op.
This is comment by source code:
* Optimize away all write operations, since the server
* will check permissions when we perform the op.
In my test, the process is like following:
#touch dir/file
NFS Server NFS Client

                       <----------      lookup (dir)
lookup ok      ------------->
                       <----------      access (dir)   (*1)
access(read only)   -----------> 
                       <----------      lookup (file)
lookup(NOENT)     ------------->
                       <----------      create (file)  (*2)

create(NOPERM) ------------->

(*1)
First to check the permissions of that dir ,and will be add to cache data.
(*2)
Since the Client had known the permission of the dir, why no used it? Does this effect to NFS client's performance?
Maybe we can check the cache first, if it not exists, then let the server to check permissions when we perform the write op. Is this better? Maybe code looks like following(not an useable patch):

nfs/dir.c renamed from nfs/dir.c.orig +0 -0
@@ -1936,6 +1936,14 @@ static int nfs_do_access(struct inode *i
        ...
	status = nfs_access_get_cached(inode, cred, &cache);

if (status == 0)
goto out;

+ /*
+ * Optimize away all write operations, since the server
+ * will check permissions when we perform the op.
+ */
+ if(((inode->i_mode & S_IFMT) == S_IFDIR)
+ && (mask & MAY_WRITE) && !(mask & MAY_READ))
+ return 0;
+
/* Be clever: ask server to check for all possible rights */ cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ; cache.cred = cred;
@@ -1973,13 +1981,6 @@ int nfs_permission(struct inode *inode,
&& (nd->flags & LOOKUP_OPEN))
goto out;
break;
- case S_IFDIR:
- /*
- * Optimize away all write operations, since the
server
- * will check permissions when we perform the
op.
- */
- if ((mask & MAY_WRITE) && !(mask & MAY_READ))
- goto out;
}

force_lookup:

------------------------------------------------------------------------
-
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#2 lore raw
In reply to Wei Yongjun
Quoted 17 lines · Wei Yongjun

Hello, everyone
When I test NFS client, I found a poblem that, if a dir we do not have
permission to write, it will let the server to check permissions when we perform the write op.
This is comment by source code:
* Optimize away all write operations, since the server
* will check permissions when we perform the op.
In my test, the process is like following:
#touch dir/file
NFS Server NFS Client

                       <----------      lookup (dir)
lookup ok      ------------->
                       <----------      access (dir)   (*1)
access(read only)   -----------> 
                       <----------      lookup (file)
lookup(NOENT)     ------------->
                       <----------      create (file)  (*2)
Quoted 7 lines

create(NOPERM) ------------->

(*1)
First to check the permissions of that dir ,and will be add to cache data. (*2)
Since the Client had known the permission of the dir, why no used it? Does this effect to NFS client's performance?

You could, but we don't really have good semantics for how to cache directory information. For files you have close-to-open caching, but for directories, there is no equivalent. I'd therefore prefer to be conservative in cases like this, rather than relying on cached information.

The other question I have is why this is really something worth optimising for? Are there really applications out there with a workload that involves lots of attempts to create files in read-only directories?

Trond

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#3 lore raw
Quoted 27 lines
Quoted 18 lines

Hello, everyone
When I test NFS client, I found a poblem that, if a dir we do not have
permission to write, it will let the server to check permissions when we perform the write op.
This is comment by source code:
* Optimize away all write operations, since the server
* will check permissions when we perform the op.
In my test, the process is like following:
#touch dir/file
NFS Server NFS Client

                       <----------      lookup (dir)
lookup ok      ------------->
                       <----------      access (dir)   (*1)
access(read only)   -----------> 
                       <----------      lookup (file)
lookup(NOENT)     ------------->
                       <----------      create (file)  (*2)
Quoted 8 lines

create(NOPERM) ------------->

(*1)
First to check the permissions of that dir ,and will be add to cache data. (*2)
Since the Client had known the permission of the dir, why no used it? Does this effect to NFS client's performance?

Quoted 6 lines

You could, but we don't really have good semantics for how to cache directory information. For files you have close-to-open caching, but for directories, there is no equivalent. I'd therefore prefer to be conservative in cases like this, rather than relying on cached information.

I think code "status = nfs_access_get_cached(inode, cred, &cache);" can do this. And it works.
Other question: why only optimize all write operations, read operations are not optimized? If read options is optimized, it can do the same things, do not use access to check permissions, and server will check permissions when we perform the read op.

Quoted 6 lines

The other question I have is why this is really something worth optimising for? Are there really applications out there with a workload that involves lots of attempts to create files in read-only directories?

Trond

Regards

Wei Yongjun

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#4 lore raw
Quoted 6 lines · Wei Yongjun

I think code "status = nfs_access_get_cached(inode, cred, &cache);" can do this. And it works.
Other question: why only optimize all write operations, read operations are not optimized? If read options is optimized, it can do the same things, do not use access to check permissions, and server will check permissions when we perform the read op.

Huh? What read operations are we failing to optimise and how?

Trond

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#5 lore raw
Quoted 11 lines
Quoted 8 lines

I think code "status = nfs_access_get_cached(inode, cred, &cache);" can do this. And it works.
Other question: why only optimize all write operations, read operations are not optimized? If read options is optimized, it can do the same things, do not use access to check permissions, and server will check permissions when we perform the read op.

Huh? What read operations are we failing to optimise and how?

I mean that read a dir, such as lookup a dir.
If I reply a getattr as that dir has no lookup permission, and then do a "cat /nfsroot/dir/file" at client, client will not send lookup procedure to server, because client used the cache data of the dir. It like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
(send nothing, used cache data)
-------no package is send-------

If no cache data exists, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) ------------------->
<------------- access reply(dir)
(has no lookup permission)

And if has permission to lookup dir, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) -------------------> (*1)
<------------- access reply(dir)
lookup(file) ------------------->
<------------- lookup reply(file)
read(file) ------------------->
<------------- read reply(file)

While you optimize all write operations to omit access procedure, can this access (*1) be omitted? Then lookup(file) will return NOPERM.

Regards
Wei Yongjun

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#6 lore raw
Quoted 50 lines · Wei Yongjun
Quoted 11 lines
Quoted 8 lines

I think code "status = nfs_access_get_cached(inode, cred, &cache);" can do this. And it works.
Other question: why only optimize all write operations, read operations are not optimized? If read options is optimized, it can do the same things, do not use access to check permissions, and server will check permissions when we perform the read op.

Huh? What read operations are we failing to optimise and how?

I mean that read a dir, such as lookup a dir.
If I reply a getattr as that dir has no lookup permission, and then do a "cat /nfsroot/dir/file" at client, client will not send lookup procedure to server, because client used the cache data of the dir. It like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
(send nothing, used cache data)
-------no package is send-------

If no cache data exists, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) ------------------->
<------------- access reply(dir)
(has no lookup permission)

And if has permission to lookup dir, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) -------------------> (*1)
<------------- access reply(dir)
lookup(file) ------------------->
<------------- lookup reply(file)
read(file) ------------------->
<------------- read reply(file)
Quoted 2 lines

While you optimize all write operations to omit access procedure, can this access (*1) be omitted? Then lookup(file) will return NOPERM.

So what if I change the permissions on the directory? What should the rules be for caching these attributes?

...and you still haven't replied to my question about what application/workload actually _cares_ about optimising for this particular case.

Trond

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#7 lore raw
Quoted 43 lines
Quoted 39 lines

I mean that read a dir, such as lookup a dir.
If I reply a getattr as that dir has no lookup permission, and then do a "cat /nfsroot/dir/file" at client, client will not send lookup procedure to server, because client used the cache data of the dir. It like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
(send nothing, used cache data)
-------no package is send-------

If no cache data exists, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) ------------------->
<------------- access reply(dir)
(has no lookup permission)

And if has permission to lookup dir, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) -------------------> (*1)
<------------- access reply(dir)
lookup(file) ------------------->
<------------- lookup reply(file)
read(file) ------------------->
<------------- read reply(file)
Quoted 3 lines

While you optimize all write operations to omit access procedure, can this access (*1) be omitted? Then lookup(file) will return NOPERM.

Quoted 7 lines

So what if I change the permissions on the directory? What should the rules be for caching these attributes?

...and you still haven't replied to my question about what application/workload actually _cares_ about optimising for this particular case.

No application cares this ^_^, just for test.
I test the read op of dir, it maybe has tiny bug in it. As you said, if I chmod of dir, client will be a little later to know this. Test step ad following:

[root@REHL ~]# mount -t nfs 192.168.0.19:/nfsroot /mnt [root@REHL ~]# ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir
[root@REHL ~]# ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[root@REHL ~]# su weiyj
[weiyj@REHL root]$ ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir [weiyj@REHL root]$ ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ssh 192.168.0.19 -l root chmod a-x /nfsroot/dir [weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ll /mnt/dir
total 0
?--------- ? ? ? ? ? /mnt/dir/file
[weiyj@REHL root]$ ll /mnt
total 4
dr--r--r-- 2 root root 4096 Jun 23 2007 dir [weiyj@REHL root]$ cat /mnt/dir/file
cat: /mnt/dir/file: Permission denied

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#8 lore raw

Sorry to trouble again, it is this a real problem of NFS?

Quoted 85 lines
Quoted 42 lines
Quoted 38 lines

I mean that read a dir, such as lookup a dir.
If I reply a getattr as that dir has no lookup permission, and then do a "cat /nfsroot/dir/file" at client, client will not send lookup procedure to server, because client used the cache data of the dir. It like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
(send nothing, used cache data)
-------no package is send-------

If no cache data exists, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) ------------------->
<------------- access reply(dir)
(has no lookup permission)

And if has permission to lookup dir, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) -------------------> (*1)
<------------- access reply(dir)
lookup(file) ------------------->
<------------- lookup reply(file)
read(file) ------------------->
<------------- read reply(file)
Quoted 4 lines

While you optimize all write operations to omit access procedure, can this access (*1) be omitted? Then lookup(file) will return NOPERM.

Quoted 8 lines

So what if I change the permissions on the directory? What should the rules be for caching these attributes?

...and you still haven't replied to my question about what application/workload actually _cares_ about optimising for this particular case.

No application cares this ^_^, just for test.
I test the read op of dir, it maybe has tiny bug in it. As you said, if I chmod of dir, client will be a little later to know this. Test step ad following:

[root@REHL ~]# mount -t nfs 192.168.0.19:/nfsroot /mnt [root@REHL ~]# ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir
[root@REHL ~]# ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[root@REHL ~]# su weiyj
[weiyj@REHL root]$ ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir [weiyj@REHL root]$ ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ssh 192.168.0.19 -l root chmod a-x /nfsroot/dir [weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ll /mnt/dir
total 0
?--------- ? ? ? ? ? /mnt/dir/file
[weiyj@REHL root]$ ll /mnt
total 4
dr--r--r-- 2 root root 4096 Jun 23 2007 dir [weiyj@REHL root]$ cat /mnt/dir/file
cat: /mnt/dir/file: Permission denied

Signature · 13 lines
A new email address of FJWAN is launched from Apr.1 2007.
The updated address is: [email protected] 
--------------------------------------------------
Wei Yongjun
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
8/F., Civil Defense Building, No.189 Guangzhou Road,
Nanjing, 210029, China
TEL: +86+25-86630523-858
COINS: 79955-858
FAX: +86+25-83317685
MAIL: [email protected]
--------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#9 lore raw
Quoted 1 line · Wei Yongjun

Sorry to trouble again, it is this a real problem of NFS?

You cannot replace an ACCESS call with checks of the mode bits. On NFS, the mode bits do _not_ suffice to determine access rights.

Trond

Quoted 77 lines
Quoted 77 lines
Quoted 42 lines
Quoted 38 lines

I mean that read a dir, such as lookup a dir.
If I reply a getattr as that dir has no lookup permission, and then do a "cat /nfsroot/dir/file" at client, client will not send lookup procedure to server, because client used the cache data of the dir. It like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
(send nothing, used cache data)
-------no package is send-------

If no cache data exists, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) ------------------->
<------------- access reply(dir)
(has no lookup permission)

And if has permission to lookup dir, it would like this:
client server
#ls /nfsroot
readdirplus ------------------>
<------------- readdirplus reply
(attribute of dir has no lookup permission)

# cat /nfsroot/dir/file
access(dir) -------------------> (*1)
<------------- access reply(dir)
lookup(file) ------------------->
<------------- lookup reply(file)
read(file) ------------------->
<------------- read reply(file)
Quoted 4 lines

While you optimize all write operations to omit access procedure, can this access (*1) be omitted? Then lookup(file) will return NOPERM.

Quoted 8 lines

So what if I change the permissions on the directory? What should the rules be for caching these attributes?

...and you still haven't replied to my question about what application/workload actually _cares_ about optimising for this particular case.

No application cares this ^_^, just for test.
I test the read op of dir, it maybe has tiny bug in it. As you said, if I chmod of dir, client will be a little later to know this. Test step ad following:

[root@REHL ~]# mount -t nfs 192.168.0.19:/nfsroot /mnt [root@REHL ~]# ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir
[root@REHL ~]# ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[root@REHL ~]# su weiyj
[weiyj@REHL root]$ ll /mnt
total 4
dr-xr-xr-x 2 root root 4096 Jun 23 2007 dir [weiyj@REHL root]$ ll /mnt/dir
total 4
-rw-r--r-- 1 root root 5 Jun 24 2007 file
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ssh 192.168.0.19 -l root chmod a-x /nfsroot/dir [weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ cat /mnt/dir/file
test
[weiyj@REHL root]$ ll /mnt/dir

Quoted 10 lines
Quoted 8 lines

total 0
?--------- ? ? ? ? ? /mnt/dir/file
[weiyj@REHL root]$ ll /mnt
total 4
dr--r--r-- 2 root root 4096 Jun 23 2007 dir
[weiyj@REHL root]$ cat /mnt/dir/file
cat: /mnt/dir/file: Permission denied

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs