~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/fhandle.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/fhandle.c (Version linux-6.12-rc7) and /fs/fhandle.c (Version linux-6.5.13)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 #include <linux/syscalls.h>                         2 #include <linux/syscalls.h>
  3 #include <linux/slab.h>                             3 #include <linux/slab.h>
  4 #include <linux/fs.h>                               4 #include <linux/fs.h>
  5 #include <linux/file.h>                             5 #include <linux/file.h>
  6 #include <linux/mount.h>                            6 #include <linux/mount.h>
  7 #include <linux/namei.h>                            7 #include <linux/namei.h>
  8 #include <linux/exportfs.h>                         8 #include <linux/exportfs.h>
  9 #include <linux/fs_struct.h>                        9 #include <linux/fs_struct.h>
 10 #include <linux/fsnotify.h>                        10 #include <linux/fsnotify.h>
 11 #include <linux/personality.h>                     11 #include <linux/personality.h>
 12 #include <linux/uaccess.h>                         12 #include <linux/uaccess.h>
 13 #include <linux/compat.h>                          13 #include <linux/compat.h>
 14 #include "internal.h"                              14 #include "internal.h"
 15 #include "mount.h"                                 15 #include "mount.h"
 16                                                    16 
 17 static long do_sys_name_to_handle(const struct     17 static long do_sys_name_to_handle(const struct path *path,
 18                                   struct file_     18                                   struct file_handle __user *ufh,
 19                                   void __user  !!  19                                   int __user *mnt_id, int fh_flags)
 20                                   int fh_flags << 
 21 {                                                  20 {
 22         long retval;                               21         long retval;
 23         struct file_handle f_handle;               22         struct file_handle f_handle;
 24         int handle_dwords, handle_bytes;           23         int handle_dwords, handle_bytes;
 25         struct file_handle *handle = NULL;         24         struct file_handle *handle = NULL;
 26                                                    25 
 27         /*                                         26         /*
 28          * We need to make sure whether the fi     27          * We need to make sure whether the file system support decoding of
 29          * the file handle if decodeable file      28          * the file handle if decodeable file handle was requested.
                                                   >>  29          * Otherwise, even empty export_operations are sufficient to opt-in
                                                   >>  30          * to encoding FIDs.
 30          */                                        31          */
 31         if (!exportfs_can_encode_fh(path->dent !!  32         if (!path->dentry->d_sb->s_export_op ||
                                                   >>  33             (!(fh_flags & EXPORT_FH_FID) &&
                                                   >>  34              !path->dentry->d_sb->s_export_op->fh_to_dentry))
 32                 return -EOPNOTSUPP;                35                 return -EOPNOTSUPP;
 33                                                    36 
 34         if (copy_from_user(&f_handle, ufh, siz     37         if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
 35                 return -EFAULT;                    38                 return -EFAULT;
 36                                                    39 
 37         if (f_handle.handle_bytes > MAX_HANDLE     40         if (f_handle.handle_bytes > MAX_HANDLE_SZ)
 38                 return -EINVAL;                    41                 return -EINVAL;
 39                                                    42 
 40         handle = kzalloc(struct_size(handle, f !!  43         handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
 41                          GFP_KERNEL);              44                          GFP_KERNEL);
 42         if (!handle)                               45         if (!handle)
 43                 return -ENOMEM;                    46                 return -ENOMEM;
 44                                                    47 
 45         /* convert handle size to multiple of      48         /* convert handle size to multiple of sizeof(u32) */
 46         handle_dwords = f_handle.handle_bytes      49         handle_dwords = f_handle.handle_bytes >> 2;
 47                                                    50 
 48         /* we ask for a non connectable maybe      51         /* we ask for a non connectable maybe decodeable file handle */
 49         retval = exportfs_encode_fh(path->dent     52         retval = exportfs_encode_fh(path->dentry,
 50                                     (struct fi     53                                     (struct fid *)handle->f_handle,
 51                                     &handle_dw     54                                     &handle_dwords, fh_flags);
 52         handle->handle_type = retval;              55         handle->handle_type = retval;
 53         /* convert handle size to bytes */         56         /* convert handle size to bytes */
 54         handle_bytes = handle_dwords * sizeof(     57         handle_bytes = handle_dwords * sizeof(u32);
 55         handle->handle_bytes = handle_bytes;       58         handle->handle_bytes = handle_bytes;
 56         if ((handle->handle_bytes > f_handle.h     59         if ((handle->handle_bytes > f_handle.handle_bytes) ||
 57             (retval == FILEID_INVALID) || (ret     60             (retval == FILEID_INVALID) || (retval < 0)) {
 58                 /* As per old exportfs_encode_     61                 /* As per old exportfs_encode_fh documentation
 59                  * we could return ENOSPC to i     62                  * we could return ENOSPC to indicate overflow
 60                  * But file system returned 25     63                  * But file system returned 255 always. So handle
 61                  * both the values                 64                  * both the values
 62                  */                                65                  */
 63                 if (retval == FILEID_INVALID |     66                 if (retval == FILEID_INVALID || retval == -ENOSPC)
 64                         retval = -EOVERFLOW;       67                         retval = -EOVERFLOW;
 65                 /*                                 68                 /*
 66                  * set the handle size to zero     69                  * set the handle size to zero so we copy only
 67                  * non variable part of the fi     70                  * non variable part of the file_handle
 68                  */                                71                  */
 69                 handle_bytes = 0;                  72                 handle_bytes = 0;
 70         } else                                     73         } else
 71                 retval = 0;                        74                 retval = 0;
 72         /* copy the mount id */                    75         /* copy the mount id */
 73         if (unique_mntid) {                    !!  76         if (put_user(real_mount(path->mnt)->mnt_id, mnt_id) ||
 74                 if (put_user(real_mount(path-> !!  77             copy_to_user(ufh, handle,
 75                              (u64 __user *) mn !!  78                          sizeof(struct file_handle) + handle_bytes))
 76                         retval = -EFAULT;      << 
 77         } else {                               << 
 78                 if (put_user(real_mount(path-> << 
 79                              (int __user *) mn << 
 80                         retval = -EFAULT;      << 
 81         }                                      << 
 82         /* copy the handle */                  << 
 83         if (retval != -EFAULT &&               << 
 84                 copy_to_user(ufh, handle,      << 
 85                              struct_size(handl << 
 86                 retval = -EFAULT;                  79                 retval = -EFAULT;
 87         kfree(handle);                             80         kfree(handle);
 88         return retval;                             81         return retval;
 89 }                                                  82 }
 90                                                    83 
 91 /**                                                84 /**
 92  * sys_name_to_handle_at: convert name to hand     85  * sys_name_to_handle_at: convert name to handle
 93  * @dfd: directory relative to which name is i     86  * @dfd: directory relative to which name is interpreted if not absolute
 94  * @name: name that should be converted to han     87  * @name: name that should be converted to handle.
 95  * @handle: resulting file handle                  88  * @handle: resulting file handle
 96  * @mnt_id: mount id of the file system contai     89  * @mnt_id: mount id of the file system containing the file
 97  *          (u64 if AT_HANDLE_MNT_ID_UNIQUE, o << 
 98  * @flag: flag value to indicate whether to fo     90  * @flag: flag value to indicate whether to follow symlink or not
 99  *        and whether a decodable file handle      91  *        and whether a decodable file handle is required.
100  *                                                 92  *
101  * @handle->handle_size indicate the space ava     93  * @handle->handle_size indicate the space available to store the
102  * variable part of the file handle in bytes.      94  * variable part of the file handle in bytes. If there is not
103  * enough space, the field is updated to retur     95  * enough space, the field is updated to return the minimum
104  * value required.                                 96  * value required.
105  */                                                97  */
106 SYSCALL_DEFINE5(name_to_handle_at, int, dfd, c     98 SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
107                 struct file_handle __user *, h !!  99                 struct file_handle __user *, handle, int __user *, mnt_id,
108                 int, flag)                        100                 int, flag)
109 {                                                 101 {
110         struct path path;                         102         struct path path;
111         int lookup_flags;                         103         int lookup_flags;
112         int fh_flags;                             104         int fh_flags;
113         int err;                                  105         int err;
114                                                   106 
115         if (flag & ~(AT_SYMLINK_FOLLOW | AT_EM !! 107         if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID))
116                      AT_HANDLE_MNT_ID_UNIQUE)) << 
117                 return -EINVAL;                   108                 return -EINVAL;
118                                                   109 
119         lookup_flags = (flag & AT_SYMLINK_FOLL    110         lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
120         fh_flags = (flag & AT_HANDLE_FID) ? EX    111         fh_flags = (flag & AT_HANDLE_FID) ? EXPORT_FH_FID : 0;
121         if (flag & AT_EMPTY_PATH)                 112         if (flag & AT_EMPTY_PATH)
122                 lookup_flags |= LOOKUP_EMPTY;     113                 lookup_flags |= LOOKUP_EMPTY;
123         err = user_path_at(dfd, name, lookup_f    114         err = user_path_at(dfd, name, lookup_flags, &path);
124         if (!err) {                               115         if (!err) {
125                 err = do_sys_name_to_handle(&p !! 116                 err = do_sys_name_to_handle(&path, handle, mnt_id, fh_flags);
126                                             fl << 
127                                             fh << 
128                 path_put(&path);                  117                 path_put(&path);
129         }                                         118         }
130         return err;                               119         return err;
131 }                                                 120 }
132                                                   121 
133 static int get_path_from_fd(int fd, struct pat !! 122 static struct vfsmount *get_vfsmount_from_fd(int fd)
134 {                                                 123 {
                                                   >> 124         struct vfsmount *mnt;
                                                   >> 125 
135         if (fd == AT_FDCWD) {                     126         if (fd == AT_FDCWD) {
136                 struct fs_struct *fs = current    127                 struct fs_struct *fs = current->fs;
137                 spin_lock(&fs->lock);             128                 spin_lock(&fs->lock);
138                 *root = fs->pwd;               !! 129                 mnt = mntget(fs->pwd.mnt);
139                 path_get(root);                << 
140                 spin_unlock(&fs->lock);           130                 spin_unlock(&fs->lock);
141         } else {                                  131         } else {
142                 struct fd f = fdget(fd);          132                 struct fd f = fdget(fd);
143                 if (!fd_file(f))               !! 133                 if (!f.file)
144                         return -EBADF;         !! 134                         return ERR_PTR(-EBADF);
145                 *root = fd_file(f)->f_path;    !! 135                 mnt = mntget(f.file->f_path.mnt);
146                 path_get(root);                << 
147                 fdput(f);                         136                 fdput(f);
148         }                                         137         }
149                                                !! 138         return mnt;
150         return 0;                              << 
151 }                                                 139 }
152                                                   140 
153 enum handle_to_path_flags {                    << 
154         HANDLE_CHECK_PERMS   = (1 << 0),       << 
155         HANDLE_CHECK_SUBTREE = (1 << 1),       << 
156 };                                             << 
157                                                << 
158 struct handle_to_path_ctx {                    << 
159         struct path root;                      << 
160         enum handle_to_path_flags flags;       << 
161         unsigned int fh_flags;                 << 
162 };                                             << 
163                                                << 
164 static int vfs_dentry_acceptable(void *context    141 static int vfs_dentry_acceptable(void *context, struct dentry *dentry)
165 {                                                 142 {
166         struct handle_to_path_ctx *ctx = conte !! 143         return 1;
167         struct user_namespace *user_ns = curre << 
168         struct dentry *d, *root = ctx->root.de << 
169         struct mnt_idmap *idmap = mnt_idmap(ct << 
170         int retval = 0;                        << 
171                                                << 
172         if (!root)                             << 
173                 return 1;                      << 
174                                                << 
175         /* Old permission model with global CA << 
176         if (!ctx->flags)                       << 
177                 return 1;                      << 
178                                                << 
179         /*                                     << 
180          * It's racy as we're not taking renam << 
181          * permissions and we just need an app << 
182          * to follow a path to the file.       << 
183          *                                     << 
184          * It's also potentially expensive on  << 
185          * there is a deep path.               << 
186          */                                    << 
187         d = dget(dentry);                      << 
188         while (d != root && !IS_ROOT(d)) {     << 
189                 struct dentry *parent = dget_p << 
190                                                << 
191                 /*                             << 
192                  * We know that we have the ab << 
193                  * as we've verified this earl << 
194                  * we also need to make sure t << 
195                  * inodes in the path that wou << 
196                  * file.                       << 
197                  */                            << 
198                 if (!privileged_wrt_inode_uidg << 
199                                                << 
200                         dput(d);               << 
201                         dput(parent);          << 
202                         return retval;         << 
203                 }                              << 
204                                                << 
205                 dput(d);                       << 
206                 d = parent;                    << 
207         }                                      << 
208                                                << 
209         if (!(ctx->flags & HANDLE_CHECK_SUBTRE << 
210                 retval = 1;                    << 
211         WARN_ON_ONCE(d != root && d != root->d << 
212         dput(d);                               << 
213         return retval;                         << 
214 }                                                 144 }
215                                                   145 
216 static int do_handle_to_path(struct file_handl !! 146 static int do_handle_to_path(int mountdirfd, struct file_handle *handle,
217                              struct handle_to_ !! 147                              struct path *path)
218 {                                                 148 {
                                                   >> 149         int retval = 0;
219         int handle_dwords;                        150         int handle_dwords;
220         struct vfsmount *mnt = ctx->root.mnt;  << 
221                                                   151 
                                                   >> 152         path->mnt = get_vfsmount_from_fd(mountdirfd);
                                                   >> 153         if (IS_ERR(path->mnt)) {
                                                   >> 154                 retval = PTR_ERR(path->mnt);
                                                   >> 155                 goto out_err;
                                                   >> 156         }
222         /* change the handle size to multiple     157         /* change the handle size to multiple of sizeof(u32) */
223         handle_dwords = handle->handle_bytes >    158         handle_dwords = handle->handle_bytes >> 2;
224         path->dentry = exportfs_decode_fh_raw( !! 159         path->dentry = exportfs_decode_fh(path->mnt,
225                                           (str    160                                           (struct fid *)handle->f_handle,
226                                           hand    161                                           handle_dwords, handle->handle_type,
227                                           ctx- !! 162                                           vfs_dentry_acceptable, NULL);
228                                           vfs_ !! 163         if (IS_ERR(path->dentry)) {
229         if (IS_ERR_OR_NULL(path->dentry)) {    !! 164                 retval = PTR_ERR(path->dentry);
230                 if (path->dentry == ERR_PTR(-E !! 165                 goto out_mnt;
231                         return -ENOMEM;        << 
232                 return -ESTALE;                << 
233         }                                         166         }
234         path->mnt = mntget(mnt);               << 
235         return 0;                                 167         return 0;
236 }                                              !! 168 out_mnt:
237                                                !! 169         mntput(path->mnt);
238 /*                                             !! 170 out_err:
239  * Allow relaxed permissions of file handles i !! 171         return retval;
240  * ability to mount the filesystem or create a << 
241  * provided @mountdirfd.                       << 
242  *                                             << 
243  * In both cases the caller may be able to get << 
244  * the encoded file handle. If the caller is o << 
245  * bind-mount we need to verify that there are << 
246  * of it that could prevent us from getting to << 
247  *                                             << 
248  * In principle, locked mounts can prevent the << 
249  * filesystem but that only applies to procfs  << 
250  * support decoding file handles.              << 
251  */                                            << 
252 static inline bool may_decode_fh(struct handle << 
253                                  unsigned int  << 
254 {                                              << 
255         struct path *root = &ctx->root;        << 
256                                                << 
257         /*                                     << 
258          * Restrict to O_DIRECTORY to provide  << 
259          * confusing api in the face of discon << 
260          *                                     << 
261          * There's only one dentry for each di << 
262          */                                    << 
263         if (!(o_flags & O_DIRECTORY))          << 
264                 return false;                  << 
265                                                << 
266         if (ns_capable(root->mnt->mnt_sb->s_us << 
267                 ctx->flags = HANDLE_CHECK_PERM << 
268         else if (is_mounted(root->mnt) &&      << 
269                  ns_capable(real_mount(root->m << 
270                             CAP_SYS_ADMIN) &&  << 
271                  !has_locked_children(real_mou << 
272                 ctx->flags = HANDLE_CHECK_PERM << 
273         else                                   << 
274                 return false;                  << 
275                                                << 
276         /* Are we able to override DAC permiss << 
277         if (!ns_capable(current_user_ns(), CAP << 
278                 return false;                  << 
279                                                << 
280         ctx->fh_flags = EXPORT_FH_DIR_ONLY;    << 
281         return true;                           << 
282 }                                                 172 }
283                                                   173 
284 static int handle_to_path(int mountdirfd, stru    174 static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
285                    struct path *path, unsigned !! 175                    struct path *path)
286 {                                                 176 {
287         int retval = 0;                           177         int retval = 0;
288         struct file_handle f_handle;              178         struct file_handle f_handle;
289         struct file_handle *handle = NULL;        179         struct file_handle *handle = NULL;
290         struct handle_to_path_ctx ctx = {};    << 
291                                                << 
292         retval = get_path_from_fd(mountdirfd,  << 
293         if (retval)                            << 
294                 goto out_err;                  << 
295                                                   180 
296         if (!capable(CAP_DAC_READ_SEARCH) && ! !! 181         /*
                                                   >> 182          * With handle we don't look at the execute bit on the
                                                   >> 183          * directory. Ideally we would like CAP_DAC_SEARCH.
                                                   >> 184          * But we don't have that
                                                   >> 185          */
                                                   >> 186         if (!capable(CAP_DAC_READ_SEARCH)) {
297                 retval = -EPERM;                  187                 retval = -EPERM;
298                 goto out_path;                 !! 188                 goto out_err;
299         }                                         189         }
300                                                << 
301         if (copy_from_user(&f_handle, ufh, siz    190         if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) {
302                 retval = -EFAULT;                 191                 retval = -EFAULT;
303                 goto out_path;                 !! 192                 goto out_err;
304         }                                         193         }
305         if ((f_handle.handle_bytes > MAX_HANDL    194         if ((f_handle.handle_bytes > MAX_HANDLE_SZ) ||
306             (f_handle.handle_bytes == 0)) {       195             (f_handle.handle_bytes == 0)) {
307                 retval = -EINVAL;                 196                 retval = -EINVAL;
308                 goto out_path;                 !! 197                 goto out_err;
309         }                                         198         }
310         handle = kmalloc(struct_size(handle, f !! 199         handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
311                          GFP_KERNEL);             200                          GFP_KERNEL);
312         if (!handle) {                            201         if (!handle) {
313                 retval = -ENOMEM;                 202                 retval = -ENOMEM;
314                 goto out_path;                 !! 203                 goto out_err;
315         }                                         204         }
316         /* copy the full handle */                205         /* copy the full handle */
317         *handle = f_handle;                       206         *handle = f_handle;
318         if (copy_from_user(&handle->f_handle,     207         if (copy_from_user(&handle->f_handle,
319                            &ufh->f_handle,        208                            &ufh->f_handle,
320                            f_handle.handle_byt    209                            f_handle.handle_bytes)) {
321                 retval = -EFAULT;                 210                 retval = -EFAULT;
322                 goto out_handle;                  211                 goto out_handle;
323         }                                         212         }
324                                                   213 
325         retval = do_handle_to_path(handle, pat !! 214         retval = do_handle_to_path(mountdirfd, handle, path);
326                                                   215 
327 out_handle:                                       216 out_handle:
328         kfree(handle);                            217         kfree(handle);
329 out_path:                                      << 
330         path_put(&ctx.root);                   << 
331 out_err:                                          218 out_err:
332         return retval;                            219         return retval;
333 }                                                 220 }
334                                                   221 
335 static long do_handle_open(int mountdirfd, str    222 static long do_handle_open(int mountdirfd, struct file_handle __user *ufh,
336                            int open_flag)         223                            int open_flag)
337 {                                                 224 {
338         long retval = 0;                          225         long retval = 0;
339         struct path path;                         226         struct path path;
340         struct file *file;                        227         struct file *file;
341         int fd;                                   228         int fd;
342                                                   229 
343         retval = handle_to_path(mountdirfd, uf !! 230         retval = handle_to_path(mountdirfd, ufh, &path);
344         if (retval)                               231         if (retval)
345                 return retval;                    232                 return retval;
346                                                   233 
347         fd = get_unused_fd_flags(open_flag);      234         fd = get_unused_fd_flags(open_flag);
348         if (fd < 0) {                             235         if (fd < 0) {
349                 path_put(&path);                  236                 path_put(&path);
350                 return fd;                        237                 return fd;
351         }                                         238         }
352         file = file_open_root(&path, "", open_    239         file = file_open_root(&path, "", open_flag, 0);
353         if (IS_ERR(file)) {                       240         if (IS_ERR(file)) {
354                 put_unused_fd(fd);                241                 put_unused_fd(fd);
355                 retval =  PTR_ERR(file);          242                 retval =  PTR_ERR(file);
356         } else {                                  243         } else {
357                 retval = fd;                      244                 retval = fd;
358                 fd_install(fd, file);             245                 fd_install(fd, file);
359         }                                         246         }
360         path_put(&path);                          247         path_put(&path);
361         return retval;                            248         return retval;
362 }                                                 249 }
363                                                   250 
364 /**                                               251 /**
365  * sys_open_by_handle_at: Open the file handle    252  * sys_open_by_handle_at: Open the file handle
366  * @mountdirfd: directory file descriptor         253  * @mountdirfd: directory file descriptor
367  * @handle: file handle to be opened              254  * @handle: file handle to be opened
368  * @flags: open flags.                            255  * @flags: open flags.
369  *                                                256  *
370  * @mountdirfd indicate the directory file des    257  * @mountdirfd indicate the directory file descriptor
371  * of the mount point. file handle is decoded     258  * of the mount point. file handle is decoded relative
372  * to the vfsmount pointed by the @mountdirfd.    259  * to the vfsmount pointed by the @mountdirfd. @flags
373  * value is same as the open(2) flags.            260  * value is same as the open(2) flags.
374  */                                               261  */
375 SYSCALL_DEFINE3(open_by_handle_at, int, mountd    262 SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
376                 struct file_handle __user *, h    263                 struct file_handle __user *, handle,
377                 int, flags)                       264                 int, flags)
378 {                                                 265 {
379         long ret;                                 266         long ret;
380                                                   267 
381         if (force_o_largefile())                  268         if (force_o_largefile())
382                 flags |= O_LARGEFILE;             269                 flags |= O_LARGEFILE;
383                                                   270 
384         ret = do_handle_open(mountdirfd, handl    271         ret = do_handle_open(mountdirfd, handle, flags);
385         return ret;                               272         return ret;
386 }                                                 273 }
387                                                   274 
388 #ifdef CONFIG_COMPAT                              275 #ifdef CONFIG_COMPAT
389 /*                                                276 /*
390  * Exactly like fs/open.c:sys_open_by_handle_a    277  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it
391  * doesn't set the O_LARGEFILE flag.              278  * doesn't set the O_LARGEFILE flag.
392  */                                               279  */
393 COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int,    280 COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
394                              struct file_handl    281                              struct file_handle __user *, handle, int, flags)
395 {                                                 282 {
396         return do_handle_open(mountdirfd, hand    283         return do_handle_open(mountdirfd, handle, flags);
397 }                                                 284 }
398 #endif                                            285 #endif
399                                                   286 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php