X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Fcompat.c;h=6b06b6bae35e52cd078efaaabe19198007a4b36d;hb=17566c3c5ed3ea8f941a135cf960387214c4f6ac;hp=a912bdf691cfca03e07eba1b5753d58779dabf66;hpb=1da177e4c3f41524e886b7f1b8a0c1fc7321cac2;p=powerpc.git diff --git a/fs/compat.c b/fs/compat.c index a912bdf691..6b06b6bae3 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -31,12 +31,13 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -806,10 +807,79 @@ static void *do_smb_super_data_conv(void *raw_data) return raw_data; } +struct compat_nfs_string { + compat_uint_t len; + compat_uptr_t data; +}; + +static inline void compat_nfs_string(struct nfs_string *dst, + struct compat_nfs_string *src) +{ + dst->data = compat_ptr(src->data); + dst->len = src->len; +} + +struct compat_nfs4_mount_data_v1 { + compat_int_t version; + compat_int_t flags; + compat_int_t rsize; + compat_int_t wsize; + compat_int_t timeo; + compat_int_t retrans; + compat_int_t acregmin; + compat_int_t acregmax; + compat_int_t acdirmin; + compat_int_t acdirmax; + struct compat_nfs_string client_addr; + struct compat_nfs_string mnt_path; + struct compat_nfs_string hostname; + compat_uint_t host_addrlen; + compat_uptr_t host_addr; + compat_int_t proto; + compat_int_t auth_flavourlen; + compat_uptr_t auth_flavours; +}; + +static int do_nfs4_super_data_conv(void *raw_data) +{ + int version = *(compat_uint_t *) raw_data; + + if (version == 1) { + struct compat_nfs4_mount_data_v1 *raw = raw_data; + struct nfs4_mount_data *real = raw_data; + + /* copy the fields backwards */ + real->auth_flavours = compat_ptr(raw->auth_flavours); + real->auth_flavourlen = raw->auth_flavourlen; + real->proto = raw->proto; + real->host_addr = compat_ptr(raw->host_addr); + real->host_addrlen = raw->host_addrlen; + compat_nfs_string(&real->hostname, &raw->hostname); + compat_nfs_string(&real->mnt_path, &raw->mnt_path); + compat_nfs_string(&real->client_addr, &raw->client_addr); + real->acdirmax = raw->acdirmax; + real->acdirmin = raw->acdirmin; + real->acregmax = raw->acregmax; + real->acregmin = raw->acregmin; + real->retrans = raw->retrans; + real->timeo = raw->timeo; + real->wsize = raw->wsize; + real->rsize = raw->rsize; + real->flags = raw->flags; + real->version = raw->version; + } + else { + return -EINVAL; + } + + return 0; +} + extern int copy_mount_options (const void __user *, unsigned long *); #define SMBFS_NAME "smbfs" #define NCPFS_NAME "ncpfs" +#define NFS4_NAME "nfs4" asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, char __user * type, unsigned long flags, @@ -845,6 +915,9 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, do_smb_super_data_conv((void *)data_page); } else if (!strcmp((char *)type_page, NCPFS_NAME)) { do_ncp_super_data_conv((void *)data_page); + } else if (!strcmp((char *)type_page, NFS4_NAME)) { + if (do_nfs4_super_data_conv((void *) data_page)) + goto out4; } } @@ -853,6 +926,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, flags, (void*)data_page); unlock_kernel(); + out4: free_page(data_page); out3: free_page(dev_page); @@ -1233,9 +1307,13 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, out: if (iov != iovstack) kfree(iov); - if ((ret + (type == READ)) > 0) - dnotify_parent(file->f_dentry, - (type == READ) ? DN_ACCESS : DN_MODIFY); + if ((ret + (type == READ)) > 0) { + struct dentry *dentry = file->f_dentry; + if (type == READ) + fsnotify_access(dentry); + else + fsnotify_modify(dentry); + } return ret; }